From 6e6c322000c6446baa0d44ddf88cce71617b554d Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Wed, 3 Oct 2007 13:16:09 +0200 Subject: [PATCH] push(c) 7dcddf6204ed5518706a76fe66fd836d81e70dd4 --- dlls/advapi32/security.c | 34 ++- dlls/advapi32/tests/security.c | 49 ++-- dlls/comctl32/tests/dpa.c | 1 - dlls/crypt32/decode.c | 6 +- dlls/d3d9/tests/device.c | 2 +- dlls/dsound/capture.c | 19 +- dlls/faultrep/faultrep.c | 9 + dlls/faultrep/faultrep.spec | 2 +- dlls/gdi32/freetype.c | 164 ++++++++++--- dlls/imagehlp/modify.c | 2 +- dlls/kernel32/cpu.c | 3 +- dlls/kernel32/heap.c | 11 +- dlls/kernel32/tests/virtual.c | 10 + dlls/mpr/wnet.c | 2 +- dlls/mshtml/editor.c | 65 ----- dlls/mshtml/htmlelem.c | 20 +- dlls/mshtml/mshtml_private.h | 4 +- dlls/mshtml/nsembed.c | 2 +- dlls/mshtml/olecmd.c | 4 +- dlls/mshtml/persist.c | 2 +- dlls/mshtml/tests/dom.c | 21 +- dlls/msi/alter.c | 2 +- dlls/ntdll/heap.c | 225 +++++++++-------- dlls/ntdll/om.c | 208 ++++++---------- dlls/ole32/compositemoniker.c | 20 +- dlls/oleaut32/tmarshal.c | 2 + dlls/opengl32/make_opengl | 5 - dlls/opengl32/opengl_norm.c | 52 ++++ dlls/opengl32/wgl.c | 55 ----- dlls/pdh/pdh_main.c | 2 +- dlls/secur32/ntlm.c | 45 +++- dlls/setupapi/devinst.c | 2 +- dlls/shlwapi/ordinal.c | 12 +- dlls/urlmon/bindctx.c | 545 +++++++++++++++++++++++++++++++++++++++++ dlls/urlmon/binding.c | 179 -------------- dlls/urlmon/tests/url.c | 318 +++++++++++++++++++++++- dlls/urlmon/umon.c | 81 +----- dlls/user32/clipboard.c | 51 ---- dlls/user32/desktop.c | 18 -- dlls/user32/listbox.c | 5 +- dlls/user32/tests/class.c | 6 +- dlls/user32/tests/dde.c | 2 +- dlls/user32/tests/msg.c | 147 +++++++++++ dlls/user32/user.exe.spec | 2 +- dlls/user32/user16.c | 36 +++ dlls/uuid/uuid.c | 1 + dlls/wined3d/baseshader.c | 3 + dlls/wined3d/glsl_shader.c | 98 +++++++- dlls/wined3d/pixelshader.c | 9 +- dlls/wined3d/wined3d_private.h | 6 +- dlls/winenas.drv/audio.c | 3 + dlls/winex11.drv/bitmap.c | 3 +- dlls/winex11.drv/dce.c | 6 + dlls/winex11.drv/init.c | 2 + dlls/winex11.drv/opengl.c | 278 ++++++++++----------- dlls/winex11.drv/window.c | 239 ++++++++++++++++++ dlls/winex11.drv/x11drv.h | 13 +- dlls/winex11.drv/xrender.c | 3 +- include/wine/server_protocol.h | 18 +- programs/net/Ru.rc | 40 +++ programs/net/net.c | 4 +- programs/net/rsrc.rc | 1 + programs/winecfg/En.rc | 62 ++--- server/change.c | 12 +- server/device.c | 2 +- server/directory.c | 14 +- server/fd.c | 10 + server/file.c | 10 +- server/file.h | 1 + server/handle.c | 92 +++++++ server/named_pipe.c | 16 +- server/object.c | 89 +++++++ server/object.h | 1 + server/protocol.def | 8 + server/request.h | 2 + server/security.h | 53 ++++ server/serial.c | 12 +- server/sock.c | 12 +- server/token.c | 162 +----------- server/trace.c | 16 ++ tools/widl/client.c | 4 +- tools/widl/header.c | 79 ++++-- tools/widl/header.h | 6 +- tools/widl/parser.y | 54 ++-- tools/widl/proxy.c | 4 +- tools/widl/server.c | 2 +- tools/widl/typegen.c | 81 +++--- tools/wine.desktop | 3 +- tools/wine.inf | 1 + 89 files changed, 2630 insertions(+), 1357 deletions(-) create mode 100644 programs/net/Ru.rc diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index cfe73f40104..23e9ad2cecb 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1819,8 +1819,15 @@ GetFileSecurityW( LPCWSTR lpFileName, { HANDLE hfile; NTSTATUS status; + DWORD access = 0; - hfile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ, + if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| + DACL_SECURITY_INFORMATION)) + access |= READ_CONTROL; + if (RequestedInformation & SACL_SECURITY_INFORMATION) + access |= ACCESS_SYSTEM_SECURITY; + + hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); if ( hfile == INVALID_HANDLE_VALUE ) return FALSE; @@ -2096,8 +2103,29 @@ SetFileSecurityW( LPCWSTR lpFileName, SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor ) { - FIXME("(%s) : stub\n", debugstr_w(lpFileName) ); - return TRUE; + HANDLE file; + DWORD access = 0; + NTSTATUS status; + + TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation, + pSecurityDescriptor ); + + if (RequestedInformation & OWNER_SECURITY_INFORMATION || + RequestedInformation & GROUP_SECURITY_INFORMATION) + access |= WRITE_OWNER; + if (RequestedInformation & SACL_SECURITY_INFORMATION) + access |= ACCESS_SYSTEM_SECURITY; + if (RequestedInformation & DACL_SECURITY_INFORMATION) + access |= WRITE_DAC; + + file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL ); + if (file == INVALID_HANDLE_VALUE) + return FALSE; + + status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor ); + CloseHandle( file ); + return set_ntstatus( status ); } /****************************************************************************** diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 6426f84f03b..3583a4dbad2 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -719,6 +719,7 @@ static void test_AccessCheck(void) if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { skip("ACLs not implemented - skipping tests\n"); + HeapFree(GetProcessHeap(), 0, Acl); return; } ok(res, "InitializeAcl failed with error %d\n", GetLastError()); @@ -1540,6 +1541,7 @@ static void test_process_security(void) if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { skip("ACLs not implemented - skipping tests\n"); + HeapFree(GetProcessHeap(), 0, Acl); return; } ok(res, "InitializeAcl failed with error %d\n", GetLastError()); @@ -1547,7 +1549,11 @@ static void test_process_security(void) /* get owner from the token we might be running as a user not admin */ res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token ); ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); - if (!res) return; + if (!res) + { + HeapFree(GetProcessHeap(), 0, Acl); + return; + } res = GetTokenInformation( token, TokenOwner, owner, sizeof(owner), &tmp ); ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); @@ -1557,7 +1563,11 @@ static void test_process_security(void) UsersSid = ((TOKEN_PRIMARY_GROUP*)group)->PrimaryGroup; CloseHandle( token ); - if (!res) return; + if (!res) + { + HeapFree(GetProcessHeap(), 0, Acl); + return; + } res = AddAccessDeniedAce(Acl, ACL_REVISION, PROCESS_VM_READ, AdminSid); ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); @@ -1979,70 +1989,70 @@ static void test_ConvertSecurityDescriptorToString() LocalFree(string); InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE(""); size = 4096; CreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size); SetSecurityDescriptorOwner(&desc, (PSID)sid_buf, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:S-1-2-0"); SetSecurityDescriptorOwner(&desc, (PSID)sid_buf, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:S-1-2-0"); size = sizeof(sid_buf); CreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size); SetSecurityDescriptorOwner(&desc, (PSID)sid_buf, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SY"); ConvertStringSidToSid("S-1-5-21-93476-23408-4576", &psid); SetSecurityDescriptorGroup(&desc, psid, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576"); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); pacl = (PACL)acl_buf; InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); ConvertStringSidToSid("S-1-5-6", &psid2); AddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)"); AddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"); AddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); pacl = (PACL)acl_buf; InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:"); SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE); AddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)"); AddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"); } @@ -2071,7 +2081,7 @@ static void test_PrivateObjectSecurity(void) ok(GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize), "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); expect_eq(ctrl, 0x8000, int, "%x"); @@ -2079,7 +2089,7 @@ static void test_PrivateObjectSecurity(void) ok(GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize), "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed err=%u\n", GetLastError()); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed err=%u\n", GetLastError()); CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); expect_eq(ctrl, 0x8004, int, "%x"); @@ -2087,7 +2097,7 @@ static void test_PrivateObjectSecurity(void) ok(GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize), "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); ok(retSize == dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Convertion failed\n"); + ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SY" "G:S-1-5-21-93476-23408-4576" "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" @@ -2100,6 +2110,7 @@ static void test_PrivateObjectSecurity(void) ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); LocalFree(sec); + HeapFree(GetProcessHeap(), 0, buf); } #undef CHECK_RESULT_AND_FREE diff --git a/dlls/comctl32/tests/dpa.c b/dlls/comctl32/tests/dpa.c index 062f6f625aa..3d7d2a71941 100644 --- a/dlls/comctl32/tests/dpa.c +++ b/dlls/comctl32/tests/dpa.c @@ -428,7 +428,6 @@ static void test_dpa(void) rc=CheckDPA(dpa, 0x123456, &dw); ok(rc, "dw=0x%x\n", dw); } - pDPA_Destroy(dpa); ret = IStream_Release(pStm); ok(!ret, "ret=%d\n", ret); diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 082c28af927..7bba04ba476 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -467,10 +467,14 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], { DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded; const BYTE *ptr = pbEncoded + 1 + lenBytes; + BOOL indefinite = FALSE; cbEncoded -= 1 + lenBytes; if (dataLen == CMSG_INDEFINITE_LENGTH) + { dataLen = cbEncoded; + indefinite = TRUE; + } else if (cbEncoded < dataLen) { TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen, @@ -501,7 +505,7 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], cbDecoded += 2; } } - if (ret && cbDecoded != dataLen) + if (ret && !indefinite && cbDecoded != dataLen) { TRACE("expected %d decoded, got %d, failing\n", dataLen, cbDecoded); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 328813c948a..2402a9713ed 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1375,7 +1375,7 @@ static void test_null_stream(void) IDirect3D9 *d3d9; HWND hwnd; HRESULT hr; - IDirect3DVertexShader9 *shader; + IDirect3DVertexShader9 *shader = NULL; IDirect3DVertexDeclaration9 *decl; DWORD shader_code[] = { 0xfffe0101, /* vs_1_1 */ diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index f0b230dcde9..9de2ecd8ddc 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -919,25 +919,22 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition( if (hres != DS_OK) WARN("IDsCaptureDriverBuffer_GetPosition failed\n"); } else if (This->device->hwi) { - DWORD pos; + DWORD pos; - EnterCriticalSection(&This->device->lock); - pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer; - TRACE("old This->device->state=%s\n",captureStateString[This->device->state]); + EnterCriticalSection(&This->device->lock); + pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer; if (lpdwCapturePosition) - *lpdwCapturePosition = pos; + *lpdwCapturePosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen; + if (lpdwReadPosition) + *lpdwReadPosition = pos; + LeaveCriticalSection(&This->device->lock); - if (lpdwReadPosition) - *lpdwReadPosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen; - LeaveCriticalSection(&This->device->lock); - - if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%d\n",*lpdwCapturePosition); - if (lpdwReadPosition) TRACE("*lpdwReadPosition=%d\n",*lpdwReadPosition); } else { WARN("no driver\n"); hres = DSERR_NODRIVER; } + TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition?*lpdwCapturePosition:-1), (lpdwReadPosition?*lpdwReadPosition:-1)); TRACE("returning %08x\n", hres); return hres; } diff --git a/dlls/faultrep/faultrep.c b/dlls/faultrep/faultrep.c index 3a0475480e6..365f143b3d6 100644 --- a/dlls/faultrep/faultrep.c +++ b/dlls/faultrep/faultrep.c @@ -102,6 +102,15 @@ BOOL WINAPI AddERExcludedApplicationA(LPCSTR lpAppFileName) return ret; } +/************************************************************************* + * ReportFault [FAULTREP.@] + */ +EFaultRepRetVal WINAPI ReportFault(LPEXCEPTION_POINTERS pep, DWORD dwOpt) +{ + FIXME("%p 0x%x stub\n", pep, dwOpt); + return frrvOk; +} + /*********************************************************************** * DllMain. */ diff --git a/dlls/faultrep/faultrep.spec b/dlls/faultrep/faultrep.spec index 77a282783c4..77e543fa779 100644 --- a/dlls/faultrep/faultrep.spec +++ b/dlls/faultrep/faultrep.spec @@ -4,7 +4,7 @@ @ stub CreateMinidumpW @ stub ReportEREvent @ stub ReportEREventDW -@ stub ReportFault +@ stdcall ReportFault(ptr long) @ stub ReportFaultDWM @ stub ReportFaultFromQueue @ stub ReportFaultToQueue diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 6036f48e08d..62563e8cf02 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -170,6 +170,7 @@ MAKE_FUNCPTR(FT_Outline_Get_Bitmap); MAKE_FUNCPTR(FT_Outline_Transform); MAKE_FUNCPTR(FT_Outline_Translate); MAKE_FUNCPTR(FT_Select_Charmap); +MAKE_FUNCPTR(FT_Set_Charmap); MAKE_FUNCPTR(FT_Set_Pixel_Sizes); MAKE_FUNCPTR(FT_Vector_Transform); static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*); @@ -2045,6 +2046,7 @@ BOOL WineEngInit(void) LOAD_FUNCPTR(FT_Outline_Transform) LOAD_FUNCPTR(FT_Outline_Translate) LOAD_FUNCPTR(FT_Select_Charmap) + LOAD_FUNCPTR(FT_Set_Charmap) LOAD_FUNCPTR(FT_Set_Pixel_Sizes) LOAD_FUNCPTR(FT_Vector_Transform) @@ -2110,7 +2112,7 @@ BOOL WineEngInit(void) if (data_dir && (unixname = HeapAlloc(GetProcessHeap(), 0, strlen(data_dir) + sizeof("/fonts/")))) { strcpy(unixname, data_dir); strcat(unixname, "/fonts/"); - ReadFontDir(unixname, FALSE); + ReadFontDir(unixname, TRUE); HeapFree(GetProcessHeap(), 0, unixname); } @@ -2720,6 +2722,61 @@ static BOOL create_child_font_list(GdiFont *font) return ret; } +static BOOL select_charmap(FT_Face ft_face, FT_Encoding encoding) +{ + FT_Error ft_err = FT_Err_Invalid_CharMap_Handle; + + if (pFT_Set_Charmap) + { + FT_Int i; + FT_CharMap cmap0, cmap1, cmap2, cmap3, cmap_def; + + cmap0 = cmap1 = cmap2 = cmap3 = cmap_def = NULL; + + for (i = 0; i < ft_face->num_charmaps; i++) + { + if (ft_face->charmaps[i]->encoding == encoding) + { + TRACE("found cmap with platform_id %u, encoding_id %u\n", + ft_face->charmaps[i]->platform_id, ft_face->charmaps[i]->encoding_id); + + switch (ft_face->charmaps[i]->platform_id) + { + default: + cmap_def = ft_face->charmaps[i]; + break; + case 0: /* Apple Unicode */ + cmap0 = ft_face->charmaps[i]; + break; + case 1: /* Macintosh */ + cmap1 = ft_face->charmaps[i]; + break; + case 2: /* ISO */ + cmap2 = ft_face->charmaps[i]; + break; + case 3: /* Microsoft */ + cmap3 = ft_face->charmaps[i]; + break; + } + } + + if (cmap3) /* prefer Microsoft cmap table */ + ft_err = pFT_Set_Charmap(ft_face, cmap3); + else if (cmap1) + ft_err = pFT_Set_Charmap(ft_face, cmap1); + else if (cmap2) + ft_err = pFT_Set_Charmap(ft_face, cmap2); + else if (cmap0) + ft_err = pFT_Set_Charmap(ft_face, cmap0); + else if (cmap_def) + ft_err = pFT_Set_Charmap(ft_face, cmap_def); + } + return ft_err == FT_Err_Ok; + } + + return pFT_Select_Charmap(ft_face, encoding) == FT_Err_Ok; +} + /************************************************************* * WineEngCreateFontInstance * @@ -3007,14 +3064,14 @@ found: ret->ntmFlags = face->ntmFlags; if (ret->charset == SYMBOL_CHARSET && - !pFT_Select_Charmap(ret->ft_face, FT_ENCODING_MS_SYMBOL)) { + select_charmap(ret->ft_face, FT_ENCODING_MS_SYMBOL)) { /* No ops */ } - else if (!pFT_Select_Charmap(ret->ft_face, FT_ENCODING_UNICODE)) { + else if (select_charmap(ret->ft_face, FT_ENCODING_UNICODE)) { /* No ops */ } else { - pFT_Select_Charmap(ret->ft_face, FT_ENCODING_APPLE_ROMAN); + select_charmap(ret->ft_face, FT_ENCODING_APPLE_ROMAN); } ret->orientation = FT_IS_SCALABLE(ret->ft_face) ? lf.lfOrientation : 0; @@ -3443,7 +3500,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, DWORD width, height, pitch, needed = 0; FT_Bitmap ft_bitmap; FT_Error err; - INT left, right, top = 0, bottom = 0; + INT left, right, top = 0, bottom = 0, adv, lsb, bbx; FT_Angle angle = 0; FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; float widthRatio = 1.0; @@ -3476,7 +3533,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, if (!font->gm[glyph_index / GM_BLOCK_SIZE]) font->gm[glyph_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE); - if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP) || font->aveWidth || lpmat) + if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || font->aveWidth || lpmat) load_flags |= FT_LOAD_NO_BITMAP; err = pFT_Load_Glyph(ft_face, glyph_index, load_flags); @@ -3494,9 +3551,9 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64; right = (INT)((ft_face->glyph->metrics.horiBearingX + ft_face->glyph->metrics.width) * widthRatio + 63) & -64; - FONT_GM(font,glyph_index)->adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6; - FONT_GM(font,glyph_index)->lsb = left >> 6; - FONT_GM(font,glyph_index)->bbx = (right - left) >> 6; + adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6; + lsb = left >> 6; + bbx = (right - left) >> 6; /* Scaling transform */ if(font->aveWidth) { @@ -3552,7 +3609,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, top = (ft_face->glyph->metrics.horiBearingY + 63) & -64; bottom = (ft_face->glyph->metrics.horiBearingY - ft_face->glyph->metrics.height) & -64; - lpgm->gmCellIncX = FONT_GM(font,glyph_index)->adv; + lpgm->gmCellIncX = adv; lpgm->gmCellIncY = 0; } else { INT xc, yc; @@ -3593,13 +3650,19 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, lpgm->gmptGlyphOrigin.x = left >> 6; lpgm->gmptGlyphOrigin.y = top >> 6; - FONT_GM(font,glyph_index)->gm = *lpgm; - FONT_GM(font,glyph_index)->init = TRUE; + if(format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) + { + FONT_GM(font,glyph_index)->gm = *lpgm; + FONT_GM(font,glyph_index)->adv = adv; + FONT_GM(font,glyph_index)->lsb = lsb; + FONT_GM(font,glyph_index)->bbx = bbx; + FONT_GM(font,glyph_index)->init = TRUE; + } if(format == GGO_METRICS) return 1; /* FIXME */ - if(ft_face->glyph->format != ft_glyph_format_outline && format != GGO_BITMAP) { + if(ft_face->glyph->format != ft_glyph_format_outline && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) { TRACE("loaded a bitmap\n"); return GDI_ERROR; } @@ -3665,34 +3728,55 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, needed = pitch * height; if(!buf || !buflen) break; - ft_bitmap.width = width; - ft_bitmap.rows = height; - ft_bitmap.pitch = pitch; - ft_bitmap.pixel_mode = ft_pixel_mode_grays; - ft_bitmap.buffer = buf; - - if(needsTransform) { - pFT_Outline_Transform(&ft_face->glyph->outline, &transMat); - } - - pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom ); - - memset(ft_bitmap.buffer, 0, buflen); - pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap); - - if(format == GGO_GRAY2_BITMAP) - mult = 4; - else if(format == GGO_GRAY4_BITMAP) - mult = 16; - else if(format == GGO_GRAY8_BITMAP) - mult = 64; - else if(format == WINE_GGO_GRAY16_BITMAP) - break; - else { - assert(0); - break; - } + switch(ft_face->glyph->format) { + case ft_glyph_format_bitmap: + { + BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf; + INT h = ft_face->glyph->bitmap.rows; + INT x; + while(h--) { + for(x = 0; x < pitch; x++) + dst[x] = (src[x / 8] & (1 << ( (7 - (x % 8))))) ? 0xff : 0; + src += ft_face->glyph->bitmap.pitch; + dst += pitch; + } + return needed; + } + case ft_glyph_format_outline: + { + ft_bitmap.width = width; + ft_bitmap.rows = height; + ft_bitmap.pitch = pitch; + ft_bitmap.pixel_mode = ft_pixel_mode_grays; + ft_bitmap.buffer = buf; + + if(needsTransform) + pFT_Outline_Transform(&ft_face->glyph->outline, &transMat); + + pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom ); + + memset(ft_bitmap.buffer, 0, buflen); + + pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap); + + if(format == GGO_GRAY2_BITMAP) + mult = 4; + else if(format == GGO_GRAY4_BITMAP) + mult = 16; + else if(format == GGO_GRAY8_BITMAP) + mult = 64; + else if(format == WINE_GGO_GRAY16_BITMAP) + return needed; + else { + assert(0); + break; + } + } + default: + FIXME("loaded glyph format %x\n", ft_face->glyph->format); + return GDI_ERROR; + } start = buf; for(row = 0; row < height; row++) { diff --git a/dlls/imagehlp/modify.c b/dlls/imagehlp/modify.c index 8d1710a6bf2..02636bd2322 100644 --- a/dlls/imagehlp/modify.c +++ b/dlls/imagehlp/modify.c @@ -327,7 +327,7 @@ BOOL WINAPI SplitSymbols( */ BOOL WINAPI UpdateDebugInfoFile( PCSTR ImageFileName, PCSTR SymbolPath, - PSTR DebugFilePath, PIMAGE_NT_HEADERS NtHeaders) + PSTR DebugFilePath, PIMAGE_NT_HEADERS32 NtHeaders) { FIXME("(%s, %s, %s, %p): stub\n", debugstr_a(ImageFileName), debugstr_a(SymbolPath), diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c index 7567af5181e..c7d366ee536 100644 --- a/dlls/kernel32/cpu.c +++ b/dlls/kernel32/cpu.c @@ -641,7 +641,8 @@ VOID WINAPI GetSystemInfo( } #elif defined(__FreeBSD__) { - int ret, len, num; + int ret, num; + unsigned len; get_cpuinfo( &cachedsi ); diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c index 9375a2ef8a8..587499ae6dc 100644 --- a/dlls/kernel32/heap.c +++ b/dlls/kernel32/heap.c @@ -356,11 +356,10 @@ HGLOBAL WINAPI GlobalAlloc( else hpflags=0; - TRACE("() flags=%04x\n", flags ); - if((flags & GMEM_MOVEABLE)==0) /* POINTER */ { palloc=HeapAlloc(GetProcessHeap(), hpflags, size); + TRACE( "(flags=%04x) returning %p\n", flags, palloc ); return (HGLOBAL) palloc; } else /* HANDLE */ @@ -399,7 +398,10 @@ HGLOBAL WINAPI GlobalAlloc( } RtlUnlockHeap(GetProcessHeap()); - return pintern ? INTERN_TO_HANDLE(pintern) : 0; + if (!pintern) return 0; + TRACE( "(flags=%04x) returning handle %p pointer %p\n", + flags, INTERN_TO_HANDLE(pintern), pintern->Pointer ); + return INTERN_TO_HANDLE(pintern); } } @@ -1206,7 +1208,8 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex ) FILE *f; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) unsigned long val; - int size_sys, mib[2]; + int mib[2]; + size_t size_sys; #elif defined(__APPLE__) unsigned int val; int mib[2]; diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 49706281e94..712ddf3996f 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -559,6 +559,15 @@ static void test_NtMapViewOfSection(void) DeleteFileA( testfile ); } +static void test_BadPtr(void) +{ + void *ptr = (void*)1; + /* We assume address 1 is not mapped. */ + ok(IsBadReadPtr(ptr,1),"IsBadReadPtr(1) failed.\n"); + ok(IsBadWritePtr(ptr,1),"IsBadWritePtr(1) failed.\n"); + ok(IsBadCodePtr(ptr),"IsBadCodePtr(1) failed.\n"); +} + START_TEST(virtual) { int argc; @@ -595,4 +604,5 @@ START_TEST(virtual) test_VirtualAlloc(); test_MapViewOfFile(); test_NtMapViewOfSection(); + test_BadPtr(); } diff --git a/dlls/mpr/wnet.c b/dlls/mpr/wnet.c index 16ac984927a..2fc8792ad26 100644 --- a/dlls/mpr/wnet.c +++ b/dlls/mpr/wnet.c @@ -1319,7 +1319,7 @@ DWORD WINAPI WNetGetResourceInformationA( LPNETRESOURCEA lpNetResource, } if (ret == WN_SUCCESS) { - LPWSTR lpSystemW; + LPWSTR lpSystemW = NULL; LPVOID lpBufferW; size = 1024; lpBufferW = HeapAlloc(GetProcessHeap(), 0, size); diff --git a/dlls/mshtml/editor.c b/dlls/mshtml/editor.c index 000299a33f4..239bba552a9 100644 --- a/dlls/mshtml/editor.c +++ b/dlls/mshtml/editor.c @@ -385,71 +385,6 @@ static void set_font_size(HTMLDocument *This, LPCWSTR size) nsIDOMDocument_Release(nsdoc); } -static BOOL is_visible_text_node(nsIDOMNode *node) -{ - nsIDOMCharacterData *char_data; - nsAString data_str; - LPCWSTR data, ptr; - PRUint32 len; - - nsIDOMNode_QueryInterface(node, &IID_nsIDOMCharacterData, (void**)&char_data); - - nsIDOMCharacterData_GetLength(char_data, &len); - - nsAString_Init(&data_str, NULL); - nsIDOMCharacterData_GetData(char_data, &data_str); - nsAString_GetData(&data_str, &data, NULL); - - if(*data == '\n') { - len--; - for(ptr=data+1; ptr && isspaceW(*ptr); ptr++) - len--; - } - - nsAString_Finish(&data_str); - - nsIDOMCharacterData_Release(char_data); - - return len != 0; -} - -static nsIDOMNode *get_child_text_node(nsIDOMNode *node, BOOL first) -{ - nsIDOMNode *iter, *iter2; - - if(first) - nsIDOMNode_GetFirstChild(node, &iter); - else - nsIDOMNode_GetLastChild(node, &iter); - - while(iter) { - PRUint16 node_type; - - nsIDOMNode_GetNodeType(iter, &node_type); - switch(node_type) { - case TEXT_NODE: - if(is_visible_text_node(iter)) - return iter; - case ELEMENT_NODE: - iter2 = get_child_text_node(iter, first); - if(iter2) { - nsIDOMNode_Release(iter); - return iter2; - } - } - - if(first) - nsIDOMNode_GetNextSibling(iter, &iter2); - else - nsIDOMNode_GetPreviousSibling(iter, &iter2); - - nsIDOMNode_Release(iter); - iter = iter2; - } - - return NULL; -} - static void handle_arrow_key(HTMLDocument *This, nsIDOMKeyEvent *event, const char * const cmds[4]) { int i=0; diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 77d50b0c85a..609a64d8bb1 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -279,8 +279,24 @@ static HRESULT WINAPI HTMLElement_get_id(IHTMLElement *iface, BSTR *p) static HRESULT WINAPI HTMLElement_get_tagName(IHTMLElement *iface, BSTR *p) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + const PRUnichar *tag; + nsAString tag_str; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&tag_str, NULL); + nsres = nsIDOMHTMLElement_GetTagName(This->nselem, &tag_str); + if(NS_SUCCEEDED(nsres)) { + nsAString_GetData(&tag_str, &tag, NULL); + *p = SysAllocString(tag); + }else { + ERR("GetTagName failed: %08x\n", nsres); + *p = NULL; + } + nsAString_Finish(&tag_str); + + return S_OK; } static HRESULT WINAPI HTMLElement_get_parentElement(IHTMLElement *iface, IHTMLElement **p) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 5a547d4a3fa..3db047fd25a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -129,7 +129,7 @@ struct HTMLDocument { BSCallback *bscallback; IMoniker *mon; - BSTR url; + LPOLESTR url; HWND hwnd; HWND tooltips_hwnd; @@ -362,7 +362,7 @@ NSContainer *NSContainer_Create(HTMLDocument*,NSContainer*); void NSContainer_Release(NSContainer*); void HTMLDocument_LockContainer(HTMLDocument*,BOOL); -void show_context_menu(HTMLDocument*,DWORD,POINT*); +void show_context_menu(HTMLDocument*,DWORD,POINT*,IDispatch*); void notif_focus(HTMLDocument*); void show_tooltip(HTMLDocument*,DWORD,DWORD,LPCWSTR); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 19bf85c1233..23b219397f9 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -997,7 +997,7 @@ static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuList FIXME("aContextFlags=%08x\n", aContextFlags); }; - show_context_menu(This->doc, dwID, &pt); + show_context_menu(This->doc, dwID, &pt, (IDispatch*)HTMLDOMNODE(get_node(This->doc, aNode))); return NS_OK; } diff --git a/dlls/mshtml/olecmd.c b/dlls/mshtml/olecmd.c index b33d305deb9..a137057bf6d 100644 --- a/dlls/mshtml/olecmd.c +++ b/dlls/mshtml/olecmd.c @@ -852,14 +852,14 @@ static const IOleCommandTargetVtbl OleCommandTargetVtbl = { OleCommandTarget_Exec }; -void show_context_menu(HTMLDocument *This, DWORD dwID, POINT *ppt) +void show_context_menu(HTMLDocument *This, DWORD dwID, POINT *ppt, IDispatch *elem) { HMENU menu_res, menu; DWORD cmdid; HRESULT hres; hres = IDocHostUIHandler_ShowContextMenu(This->hostui, dwID, ppt, - (IUnknown*)CMDTARGET(This), (IDispatch*)HTMLDOC(This)); + (IUnknown*)CMDTARGET(This), elem); if(hres == S_OK) return; diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index abee74349b6..70da02ee40b 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -175,7 +175,7 @@ void set_current_mon(HTMLDocument *This, IMoniker *mon) } if(This->url) { - SysFreeString(This->url); + CoTaskMemFree(This->url); This->url = NULL; } diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 3c7a18a250c..fefe0541bba 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -80,11 +80,29 @@ static void _test_node_name(unsigned line, IUnknown *unk, const char *exname) hres = IHTMLDOMNode_get_nodeName(node, &name); IHTMLDOMNode_Release(node); ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres); - ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected HTML\n", dbgstr_w(name)); + ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", dbgstr_w(name), exname); SysFreeString(name); } +#define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n) +static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag) +{ + IHTMLElement *elem; + BSTR tag; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem); + ok_(__FILE__, line) (hres == S_OK, "QueryInterface(IID_IHTMLElement) failed: %08x\n", hres); + + hres = IHTMLElement_get_tagName(elem, &tag); + IHTMLElement_Release(elem); + ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres); + ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", dbgstr_w(tag), extag); + + SysFreeString(tag); +} + static void test_doc_elem(IHTMLDocument2 *doc) { IHTMLElement *elem; @@ -99,6 +117,7 @@ static void test_doc_elem(IHTMLDocument2 *doc) ok(hres == S_OK, "get_documentElement failed: %08x\n", hres); test_node_name((IUnknown*)elem, "HTML"); + test_elem_tag((IUnknown*)elem, "HTML"); IHTMLElement_Release(elem); } diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c index 587b4beaae6..e0a1b91ffe7 100644 --- a/dlls/msi/alter.c +++ b/dlls/msi/alter.c @@ -202,8 +202,8 @@ static UINT ALTER_delete( struct tagMSIVIEW *view ) MSIALTERVIEW *av = (MSIALTERVIEW*)view; TRACE("%p\n", av ); - msi_free( av ); av->table->ops->delete( av->table ); + msi_free( av ); return ERROR_SUCCESS; } diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index c08710642eb..e6ba48cb8cd 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -43,12 +43,10 @@ #include "wine/server.h" WINE_DEFAULT_DEBUG_CHANNEL(heap); -WINE_DECLARE_DEBUG_CHANNEL(heap_poison); -/* Note: the heap data structures are based on what Pietrek describes in his - * book 'Windows 95 System Programming Secrets'. The layout is not exactly - * the same, but could be easily adapted if it turns out some programs - * require it. +/* Note: the heap data structures are loosely based on what Pietrek describes in his + * book 'Windows 95 System Programming Secrets', with some adaptations for + * better compatibility with NT. */ /* FIXME: use SIZE_T for 'size' structure members, but we need to make sure @@ -106,11 +104,12 @@ struct tagHEAP; typedef struct tagSUBHEAP { - DWORD size; /* Size of the whole sub-heap */ - DWORD commitSize; /* Committed size of the sub-heap */ - DWORD headerSize; /* Size of the heap header */ - struct tagSUBHEAP *next; /* Next sub-heap */ + void *base; /* Base address of the sub-heap memory block */ + SIZE_T size; /* Size of the whole sub-heap */ + SIZE_T commitSize; /* Committed size of the sub-heap */ + struct list entry; /* Entry in sub-heap list */ struct tagHEAP *heap; /* Main heap structure */ + DWORD headerSize; /* Size of the heap header */ DWORD magic; /* Magic number */ } SUBHEAP; @@ -118,12 +117,15 @@ typedef struct tagSUBHEAP typedef struct tagHEAP { + DWORD unknown[3]; + DWORD flags; /* Heap flags */ + DWORD force_flags; /* Forced heap flags for debugging */ SUBHEAP subheap; /* First sub-heap */ struct list entry; /* Entry in process heap list */ + struct list subheap_list; /* Sub-heap list */ + DWORD magic; /* Magic number */ RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */ FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */ - DWORD flags; /* Heap flags */ - DWORD magic; /* Magic number */ } HEAP; #define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24))) @@ -138,7 +140,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL qu /* mark a block of memory as free for debugging purposes */ static inline void mark_block_free( void *ptr, SIZE_T size ) { - if (TRACE_ON(heap) || TRACE_ON(heap_poison)) memset( ptr, ARENA_FREE_FILLER, size ); + if (TRACE_ON(heap) || WARN_ON(heap)) memset( ptr, ARENA_FREE_FILLER, size ); #ifdef VALGRIND_MAKE_NOACCESS VALGRIND_DISCARD( VALGRIND_MAKE_NOACCESS( ptr, size )); #endif @@ -158,7 +160,7 @@ static inline void mark_block_uninitialized( void *ptr, SIZE_T size ) #ifdef VALGRIND_MAKE_WRITABLE VALGRIND_DISCARD( VALGRIND_MAKE_WRITABLE( ptr, size )); #endif - if (TRACE_ON(heap) || TRACE_ON(heap_poison)) + if (TRACE_ON(heap) || WARN_ON(heap)) { memset( ptr, ARENA_INUSE_FILLER, size ); #ifdef VALGRIND_MAKE_WRITABLE @@ -226,14 +228,8 @@ static void HEAP_Dump( HEAP *heap ) char *ptr; DPRINTF( "Heap: %p\n", heap ); - DPRINTF( "Next: %p Sub-heaps: %p", - LIST_ENTRY( heap->entry.next, HEAP, entry ), &heap->subheap ); - subheap = &heap->subheap; - while (subheap->next) - { - DPRINTF( " -> %p", subheap->next ); - subheap = subheap->next; - } + DPRINTF( "Next: %p Sub-heaps:", LIST_ENTRY( heap->entry.next, HEAP, entry ) ); + LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) DPRINTF( " %p", subheap ); DPRINTF( "\nFree lists:\n Block Stat Size Id\n" ); for (i = 0; i < HEAP_NB_FREE_LISTS; i++) @@ -242,16 +238,15 @@ static void HEAP_Dump( HEAP *heap ) LIST_ENTRY( heap->freeList[i].arena.entry.prev, ARENA_FREE, entry ), LIST_ENTRY( heap->freeList[i].arena.entry.next, ARENA_FREE, entry )); - subheap = &heap->subheap; - while (subheap) + LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) { SIZE_T freeSize = 0, usedSize = 0, arenaSize = subheap->headerSize; - DPRINTF( "\n\nSub-heap %p: size=%08x committed=%08x\n", - subheap, subheap->size, subheap->commitSize ); + DPRINTF( "\n\nSub-heap %p: base=%p size=%08lx committed=%08lx\n", + subheap, subheap->base, subheap->size, subheap->commitSize ); DPRINTF( "\n Block Stat Size Id\n" ); - ptr = (char*)subheap + subheap->headerSize; - while (ptr < (char *)subheap + subheap->size) + ptr = (char *)subheap->base + subheap->headerSize; + while (ptr < (char *)subheap->base + subheap->size) { if (*(DWORD *)ptr & ARENA_FLAG_FREE) { @@ -282,10 +277,9 @@ static void HEAP_Dump( HEAP *heap ) usedSize += pArena->size & ARENA_SIZE_MASK; } } - DPRINTF( "\nTotal: Size=%08x Committed=%08x Free=%08lx Used=%08lx Arenas=%08lx (%ld%%)\n\n", + DPRINTF( "\nTotal: Size=%08lx Committed=%08lx Free=%08lx Used=%08lx Arenas=%08lx (%ld%%)\n\n", subheap->size, subheap->commitSize, freeSize, usedSize, arenaSize, (arenaSize * 100) / subheap->size ); - subheap = subheap->next; } } @@ -346,7 +340,7 @@ static HEAP *HEAP_GetPtr( ERR("Invalid heap %p!\n", heap ); return NULL; } - if ((TRACE_ON(heap)|| TRACE_ON(heap_poison)) && !HEAP_IsRealArena( heapPtr, 0, NULL, NOISY )) + if (TRACE_ON(heap) && !HEAP_IsRealArena( heapPtr, 0, NULL, NOISY )) { HEAP_Dump( heapPtr ); assert( FALSE ); @@ -390,16 +384,13 @@ static inline void HEAP_InsertFreeBlock( HEAP *heap, ARENA_FREE *pArena, BOOL la */ static SUBHEAP *HEAP_FindSubHeap( const HEAP *heap, /* [in] Heap pointer */ - LPCVOID ptr /* [in] Address */ -) { - const SUBHEAP *sub = &heap->subheap; - while (sub) - { - if (((const char *)ptr >= (const char *)sub) && - ((const char *)ptr < (const char *)sub + sub->size - sizeof(ARENA_INUSE))) - return (SUBHEAP *)sub; - sub = sub->next; - } + LPCVOID ptr ) /* [in] Address */ +{ + SUBHEAP *sub; + LIST_FOR_EACH_ENTRY( sub, &heap->subheap_list, SUBHEAP, entry ) + if (((const char *)ptr >= (const char *)sub->base) && + ((const char *)ptr < (const char *)sub->base + sub->size - sizeof(ARENA_INUSE))) + return sub; return NULL; } @@ -412,12 +403,12 @@ static SUBHEAP *HEAP_FindSubHeap( static inline BOOL HEAP_Commit( SUBHEAP *subheap, ARENA_INUSE *pArena, SIZE_T data_size ) { void *ptr = (char *)(pArena + 1) + data_size + sizeof(ARENA_FREE); - SIZE_T size = (char *)ptr - (char *)subheap; + SIZE_T size = (char *)ptr - (char *)subheap->base; size = (size + COMMIT_MASK) & ~COMMIT_MASK; if (size > subheap->size) size = subheap->size; if (size <= subheap->commitSize) return TRUE; size -= subheap->commitSize; - ptr = (char *)subheap + subheap->commitSize; + ptr = (char *)subheap->base + subheap->commitSize; if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &size, MEM_COMMIT, get_protection_type( subheap->heap->flags ) )) { @@ -439,18 +430,18 @@ static inline BOOL HEAP_Decommit( SUBHEAP *subheap, void *ptr ) { void *addr; SIZE_T decommit_size; - SIZE_T size = (char *)ptr - (char *)subheap; + SIZE_T size = (char *)ptr - (char *)subheap->base; /* round to next block and add one full block */ size = ((size + COMMIT_MASK) & ~COMMIT_MASK) + COMMIT_MASK + 1; if (size >= subheap->commitSize) return TRUE; decommit_size = subheap->commitSize - size; - addr = (char *)subheap + size; + addr = (char *)subheap->base + size; if (NtFreeVirtualMemory( NtCurrentProcess(), &addr, &decommit_size, MEM_DECOMMIT )) { WARN("Could not decommit %08lx bytes at %p for heap %p\n", - decommit_size, (char *)subheap + size, subheap->heap ); + decommit_size, (char *)subheap->base + size, subheap->heap ); return FALSE; } subheap->commitSize -= decommit_size; @@ -478,12 +469,13 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, SIZE_T size ) /* If debugging, erase the freed block content */ pEnd = (char *)ptr + size; - if (pEnd > (char *)subheap + subheap->commitSize) pEnd = (char *)subheap + subheap->commitSize; + if (pEnd > (char *)subheap->base + subheap->commitSize) + pEnd = (char *)subheap->base + subheap->commitSize; if (pEnd > (char *)(pFree + 1)) mark_block_free( pFree + 1, pEnd - (char *)(pFree + 1) ); /* Check if next block is free also */ - if (((char *)ptr + size < (char *)subheap + subheap->size) && + if (((char *)ptr + size < (char *)subheap->base + subheap->size) && (*(DWORD *)((char *)ptr + size) & ARENA_FLAG_FREE)) { /* Remove the next arena from the free list */ @@ -495,7 +487,7 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, SIZE_T size ) /* Set the next block PREV_FREE flag and pointer */ - last = ((char *)ptr + size >= (char *)subheap + subheap->size); + last = ((char *)ptr + size >= (char *)subheap->base + subheap->size); if (!last) { DWORD *pNext = (DWORD *)((char *)ptr + size); @@ -537,24 +529,23 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena ) HEAP_CreateFreeBlock( subheap, pFree, size ); size = (pFree->size & ARENA_SIZE_MASK) + sizeof(ARENA_FREE); - if ((char *)pFree + size < (char *)subheap + subheap->size) + if ((char *)pFree + size < (char *)subheap->base + subheap->size) return; /* Not the last block, so nothing more to do */ /* Free the whole sub-heap if it's empty and not the original one */ - if (((char *)pFree == (char *)subheap + subheap->headerSize) && + if (((char *)pFree == (char *)subheap->base + subheap->headerSize) && (subheap != &subheap->heap->subheap)) { SIZE_T size = 0; - SUBHEAP *pPrev = &subheap->heap->subheap; + void *addr = subheap->base; /* Remove the free block from the list */ list_remove( &pFree->entry ); /* Remove the subheap from the list */ - while (pPrev && (pPrev->next != subheap)) pPrev = pPrev->next; - if (pPrev) pPrev->next = subheap->next; + list_remove( &subheap->entry ); /* Free the memory */ subheap->magic = 0; - NtFreeVirtualMemory( NtCurrentProcess(), (void **)&subheap, &size, MEM_RELEASE ); + NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); return; } @@ -582,7 +573,7 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, SIZE_T size) { /* Turn off PREV_FREE flag in next block */ char *pNext = (char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK); - if (pNext < (char *)subheap + subheap->size) + if (pNext < (char *)subheap->base + subheap->size) *(DWORD *)pNext &= ~ARENA_FLAG_PREV_FREE; } } @@ -590,8 +581,8 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, SIZE_T size) /*********************************************************************** * HEAP_InitSubHeap */ -static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags, - SIZE_T commitSize, SIZE_T totalSize ) +static SUBHEAP *HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags, + SIZE_T commitSize, SIZE_T totalSize ) { SUBHEAP *subheap; FREE_LIST_ENTRY *pEntry; @@ -605,33 +596,39 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags, &commitSize, MEM_COMMIT, get_protection_type( flags ) )) { WARN("Could not commit %08lx bytes for sub-heap %p\n", commitSize, address ); - return FALSE; + return NULL; } - /* Fill the sub-heap structure */ - - subheap = (SUBHEAP *)address; - subheap->heap = heap; - subheap->size = totalSize; - subheap->commitSize = commitSize; - subheap->magic = SUBHEAP_MAGIC; - - if ( subheap != (SUBHEAP *)heap ) + if (heap) { /* If this is a secondary subheap, insert it into list */ + subheap = (SUBHEAP *)address; + subheap->base = address; + subheap->heap = heap; + subheap->size = totalSize; + subheap->commitSize = commitSize; + subheap->magic = SUBHEAP_MAGIC; subheap->headerSize = ROUND_SIZE( sizeof(SUBHEAP) ); - subheap->next = heap->subheap.next; - heap->subheap.next = subheap; + list_add_head( &heap->subheap_list, &subheap->entry ); } else { /* If this is a primary subheap, initialize main heap */ - subheap->headerSize = ROUND_SIZE( sizeof(HEAP) ); - subheap->next = NULL; + heap = (HEAP *)address; heap->flags = flags; heap->magic = HEAP_MAGIC; + list_init( &heap->subheap_list ); + + subheap = &heap->subheap; + subheap->base = address; + subheap->heap = heap; + subheap->size = totalSize; + subheap->commitSize = commitSize; + subheap->magic = SUBHEAP_MAGIC; + subheap->headerSize = ROUND_SIZE( sizeof(HEAP) ); + list_add_head( &heap->subheap_list, &subheap->entry ); /* Build the free lists */ @@ -647,8 +644,6 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags, if (!processHeap) /* do it by hand to avoid memory allocations */ { - if(TRACE_ON(heap_poison)) - TRACE_(heap_poison)("poisioning heap\n"); heap->critSection.DebugInfo = &process_heap_critsect_debug; heap->critSection.LockCount = -1; heap->critSection.RecursionCount = 0; @@ -679,10 +674,10 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags, /* Create the first free block */ - HEAP_CreateFreeBlock( subheap, (LPBYTE)subheap + subheap->headerSize, + HEAP_CreateFreeBlock( subheap, (LPBYTE)subheap->base + subheap->headerSize, subheap->size - subheap->headerSize ); - return TRUE; + return subheap; } /*********************************************************************** @@ -695,6 +690,7 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, void *base, DWORD flags, SIZE_T commitSize, SIZE_T totalSize ) { LPVOID address = base; + SUBHEAP *ret; /* round-up sizes on a 64K boundary */ totalSize = (totalSize + 0xffff) & 0xffff0000; @@ -715,15 +711,12 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, void *base, DWORD flags, /* Initialize subheap */ - if (!HEAP_InitSubHeap( heap ? heap : (HEAP *)address, - address, flags, commitSize, totalSize )) + if (!(ret = HEAP_InitSubHeap( heap, address, flags, commitSize, totalSize ))) { SIZE_T size = 0; if (!base) NtFreeVirtualMemory( NtCurrentProcess(), &address, &size, MEM_RELEASE ); - return NULL; } - - return (SUBHEAP *)address; + return ret; } @@ -781,7 +774,7 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, SIZE_T size, subheap, total_size, heap ); *ppSubHeap = subheap; - return (ARENA_FREE *)(subheap + 1); + return (ARENA_FREE *)((char *)subheap->base + subheap->headerSize); } @@ -795,7 +788,7 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const ARENA_FREE *ptr ) int i; const SUBHEAP *subheap = HEAP_FindSubHeap( heap, ptr ); if (!subheap) return FALSE; - if ((const char *)ptr >= (const char *)subheap + subheap->headerSize) return TRUE; + if ((const char *)ptr >= (const char *)subheap->base + subheap->headerSize) return TRUE; if (subheap != &heap->subheap) return FALSE; for (i = 0; i < HEAP_NB_FREE_LISTS; i++) if (ptr == (const void *)&heap->freeList[i].arena) return TRUE; @@ -809,7 +802,7 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const ARENA_FREE *ptr ) static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) { ARENA_FREE *prev, *next; - char *heapEnd = (char *)subheap + subheap->size; + char *heapEnd = (char *)subheap->base + subheap->size; /* Check for unaligned pointers */ if ( (ULONG_PTR)pArena % ALIGNMENT != 0 ) @@ -900,7 +893,7 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) */ static BOOL HEAP_ValidateInUseArena( const SUBHEAP *subheap, const ARENA_INUSE *pArena, BOOL quiet ) { - const char *heapEnd = (const char *)subheap + subheap->size; + const char *heapEnd = (const char *)subheap->base + subheap->size; /* Check for unaligned pointers */ if ( (ULONG_PTR)pArena % ALIGNMENT != 0 ) @@ -1015,7 +1008,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */ const ARENA_INUSE *arena = (const ARENA_INUSE *)block - 1; if (!(subheap = HEAP_FindSubHeap( heapPtr, arena )) || - ((const char *)arena < (char *)subheap + subheap->headerSize)) + ((const char *)arena < (char *)subheap->base + subheap->headerSize)) { if (quiet == NOISY) ERR("Heap %p: block %p is not inside heap\n", heapPtr, block ); @@ -1030,11 +1023,10 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */ return ret; } - subheap = &heapPtr->subheap; - while (subheap && ret) + LIST_FOR_EACH_ENTRY( subheap, &heapPtr->subheap_list, SUBHEAP, entry ) { - char *ptr = (char *)subheap + subheap->headerSize; - while (ptr < (char *)subheap + subheap->size) + char *ptr = (char *)subheap->base + subheap->headerSize; + while (ptr < (char *)subheap->base + subheap->size) { if (*(DWORD *)ptr & ARENA_FLAG_FREE) { @@ -1053,7 +1045,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */ ptr += sizeof(ARENA_INUSE) + (*(DWORD *)ptr & ARENA_SIZE_MASK); } } - subheap = subheap->next; + if (!ret) break; } if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection ); @@ -1105,9 +1097,11 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c { processHeap = subheap->heap; /* assume the first heap we create is the process main heap */ list_init( &processHeap->entry ); + /* make sure structure alignment is correct */ + assert( (ULONG_PTR)&processHeap->freeList % ALIGNMENT == 0 ); } - return (HANDLE)subheap; + return (HANDLE)subheap->heap; } @@ -1126,7 +1120,9 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) { HEAP *heapPtr = HEAP_GetPtr( heap ); - SUBHEAP *subheap; + SUBHEAP *subheap, *next; + SIZE_T size; + void *addr; TRACE("%p\n", heap ); if (!heapPtr) return heap; @@ -1140,15 +1136,18 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) heapPtr->critSection.DebugInfo->Spare[0] = 0; RtlDeleteCriticalSection( &heapPtr->critSection ); - subheap = &heapPtr->subheap; - while (subheap) + + LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heapPtr->subheap_list, SUBHEAP, entry ) { - SUBHEAP *next = subheap->next; - SIZE_T size = 0; - void *addr = subheap; + if (subheap == &heapPtr->subheap) continue; /* do this one last */ + list_remove( &subheap->entry ); + size = 0; + addr = subheap->base; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); - subheap = next; } + size = 0; + addr = heapPtr->subheap.base; + NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); return 0; } @@ -1274,7 +1273,7 @@ BOOLEAN WINAPI RtlFreeHeap( HANDLE heap, ULONG flags, PVOID ptr ) pInUse = (ARENA_INUSE *)ptr - 1; if (!(subheap = HEAP_FindSubHeap( heapPtr, pInUse ))) goto error; - if ((char *)pInUse < (char *)subheap + subheap->headerSize) goto error; + if ((char *)pInUse < (char *)subheap->base + subheap->headerSize) goto error; if (!HEAP_ValidateInUseArena( subheap, pInUse, QUIET )) goto error; /* Turn the block into a free block */ @@ -1343,7 +1342,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size pArena = (ARENA_INUSE *)ptr - 1; if (!(subheap = HEAP_FindSubHeap( heapPtr, pArena ))) goto error; - if ((char *)pArena < (char *)subheap + subheap->headerSize) goto error; + if ((char *)pArena < (char *)subheap->base + subheap->headerSize) goto error; if (!HEAP_ValidateInUseArena( subheap, pArena, QUIET )) goto error; /* Check if we need to grow the block */ @@ -1352,7 +1351,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size if (rounded_size > oldSize) { char *pNext = (char *)(pArena + 1) + oldSize; - if ((pNext < (char *)subheap + subheap->size) && + if ((pNext < (char *)subheap->base + subheap->size) && (*(DWORD *)pNext & ARENA_FLAG_FREE) && (oldSize + (*(DWORD *)pNext & ARENA_SIZE_MASK) + sizeof(ARENA_FREE) >= rounded_size)) { @@ -1607,21 +1606,19 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr ) { TRACE("begin walking of heap %p.\n", heap); currentheap = &heapPtr->subheap; - ptr = (char*)currentheap + currentheap->headerSize; + ptr = (char*)currentheap->base + currentheap->headerSize; } else { ptr = entry->lpData; - sub = &heapPtr->subheap; - while (sub) + LIST_FOR_EACH_ENTRY( sub, &heapPtr->subheap_list, SUBHEAP, entry ) { - if (((char *)ptr >= (char *)sub) && - ((char *)ptr < (char *)sub + sub->size)) + if (((char *)ptr >= (char *)sub->base) && + ((char *)ptr < (char *)sub->base + sub->size)) { currentheap = sub; break; } - sub = sub->next; region_index++; } if (currentheap == NULL) @@ -1644,15 +1641,17 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr ) else ptr += entry->cbData; /* point to next arena */ - if (ptr > (char *)currentheap + currentheap->size - 1) + if (ptr > (char *)currentheap->base + currentheap->size - 1) { /* proceed with next subheap */ - if (!(currentheap = currentheap->next)) + struct list *next = list_next( &heapPtr->subheap_list, ¤theap->entry ); + if (!next) { /* successfully finished */ TRACE("end reached.\n"); ret = STATUS_NO_MORE_ENTRIES; goto HW_end; } - ptr = (char*)currentheap + currentheap->headerSize; + currentheap = LIST_ENTRY( next, SUBHEAP, entry ); + ptr = (char *)currentheap->base + currentheap->headerSize; } } @@ -1685,16 +1684,16 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr ) entry->iRegionIndex = region_index; /* first element of heap ? */ - if (ptr == (char *)(currentheap + currentheap->headerSize)) + if (ptr == (char *)currentheap->base + currentheap->headerSize) { entry->wFlags |= PROCESS_HEAP_REGION; entry->u.Region.dwCommittedSize = currentheap->commitSize; entry->u.Region.dwUnCommittedSize = currentheap->size - currentheap->commitSize; entry->u.Region.lpFirstBlock = /* first valid block */ - currentheap + currentheap->headerSize; + (char *)currentheap->base + currentheap->headerSize; entry->u.Region.lpLastBlock = /* first invalid block */ - currentheap + currentheap->size; + (char *)currentheap->base + currentheap->size; } ret = STATUS_SUCCESS; if (TRACE_ON(heap)) HEAP_DumpEntry(entry); diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index 06ec9f63ab4..7cb7f06006a 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -162,152 +162,84 @@ NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle, * * An ntdll analogue to GetKernelObjectSecurity(). * - * NOTES - * only the lowest 4 bit of SecurityObjectInformationClass are used - * 0x7-0xf returns STATUS_ACCESS_DENIED (even running with system privileges) - * - * FIXME - * We are constructing a fake sid (Administrators:Full, System:Full, Everyone:Read) */ NTSTATUS WINAPI NtQuerySecurityObject( IN HANDLE Object, IN SECURITY_INFORMATION RequestedInformation, - OUT PSECURITY_DESCRIPTOR pSecurityDesriptor, + OUT PSECURITY_DESCRIPTOR pSecurityDescriptor, IN ULONG Length, OUT PULONG ResultLength) { - static const SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY}; - static const SID_IDENTIFIER_AUTHORITY worldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY}; - BYTE Buffer[256]; - PISECURITY_DESCRIPTOR_RELATIVE psd = (PISECURITY_DESCRIPTOR_RELATIVE)Buffer; - UINT BufferIndex = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - - FIXME("(%p,0x%08x,%p,0x%08x,%p) stub!\n", - Object, RequestedInformation, pSecurityDesriptor, Length, ResultLength); - - RequestedInformation &= 0x0000000f; - - ZeroMemory(Buffer, 256); - RtlCreateSecurityDescriptor((PSECURITY_DESCRIPTOR)psd, SECURITY_DESCRIPTOR_REVISION); - psd->Control = SE_SELF_RELATIVE | - ((RequestedInformation & DACL_SECURITY_INFORMATION) ? SE_DACL_PRESENT:0); - - /* owner: administrator S-1-5-20-220*/ - if (OWNER_SECURITY_INFORMATION & RequestedInformation) - { - SID* psid = (SID*)&(Buffer[BufferIndex]); - - psd->Owner = BufferIndex; - BufferIndex += RtlLengthRequiredSid(2); - - psid->Revision = SID_REVISION; - psid->SubAuthorityCount = 2; - psid->IdentifierAuthority = localSidAuthority; - psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID; - psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS; - } - - /* group: built in domain S-1-5-12 */ - if (GROUP_SECURITY_INFORMATION & RequestedInformation) - { - SID* psid = (SID*) &(Buffer[BufferIndex]); - - psd->Group = BufferIndex; - BufferIndex += RtlLengthRequiredSid(1); - - psid->Revision = SID_REVISION; - psid->SubAuthorityCount = 1; - psid->IdentifierAuthority = localSidAuthority; - psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID; - } - - /* discretionary ACL */ - if (DACL_SECURITY_INFORMATION & RequestedInformation) - { - /* acl header */ - PACL pacl = (PACL)&(Buffer[BufferIndex]); - PACCESS_ALLOWED_ACE pace; - SID* psid; - - psd->Dacl = BufferIndex; - - pacl->AclRevision = MIN_ACL_REVISION; - pacl->AceCount = 3; - pacl->AclSize = BufferIndex; /* storing the start index temporary */ - - BufferIndex += sizeof(ACL); - - /* ACE System - full access */ - pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]); - BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD); - - pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; - pace->Header.AceFlags = CONTAINER_INHERIT_ACE; - pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1); - pace->Mask = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; - pace->SidStart = BufferIndex; - - /* SID S-1-5-12 (System) */ - psid = (SID*)&(Buffer[BufferIndex]); - - BufferIndex += RtlLengthRequiredSid(1); - - psid->Revision = SID_REVISION; - psid->SubAuthorityCount = 1; - psid->IdentifierAuthority = localSidAuthority; - psid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID; - - /* ACE Administrators - full access*/ - pace = (PACCESS_ALLOWED_ACE) &(Buffer[BufferIndex]); - BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD); - - pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; - pace->Header.AceFlags = CONTAINER_INHERIT_ACE; - pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(2); - pace->Mask = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; - pace->SidStart = BufferIndex; - - /* S-1-5-12 (Administrators) */ - psid = (SID*)&(Buffer[BufferIndex]); - - BufferIndex += RtlLengthRequiredSid(2); - - psid->Revision = SID_REVISION; - psid->SubAuthorityCount = 2; - psid->IdentifierAuthority = localSidAuthority; - psid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID; - psid->SubAuthority[1] = DOMAIN_ALIAS_RID_ADMINS; - - /* ACE Everyone - read access */ - pace = (PACCESS_ALLOWED_ACE)&(Buffer[BufferIndex]); - BufferIndex += sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD); - - pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; - pace->Header.AceFlags = CONTAINER_INHERIT_ACE; - pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD) + RtlLengthRequiredSid(1); - pace->Mask = READ_CONTROL| 0x19; - pace->SidStart = BufferIndex; - - /* SID S-1-1-0 (Everyone) */ - psid = (SID*)&(Buffer[BufferIndex]); - - BufferIndex += RtlLengthRequiredSid(1); - - psid->Revision = SID_REVISION; - psid->SubAuthorityCount = 1; - psid->IdentifierAuthority = worldSidAuthority; - psid->SubAuthority[0] = 0; - - /* calculate used bytes */ - pacl->AclSize = BufferIndex - pacl->AclSize; - } - *ResultLength = BufferIndex; - TRACE("len=%u\n", *ResultLength); - if (Length < *ResultLength) return STATUS_BUFFER_TOO_SMALL; - memcpy(pSecurityDesriptor, Buffer, *ResultLength); - - return STATUS_SUCCESS; + PISECURITY_DESCRIPTOR_RELATIVE psd = pSecurityDescriptor; + NTSTATUS status; + unsigned int buffer_size = 512; + BOOLEAN need_more_memory = FALSE; + + TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", + Object, RequestedInformation, pSecurityDescriptor, Length, ResultLength); + + do + { + char *buffer = RtlAllocateHeap(GetProcessHeap(), 0, buffer_size); + if (!buffer) + return STATUS_NO_MEMORY; + + SERVER_START_REQ( get_security_object ) + { + req->handle = Object; + req->security_info = RequestedInformation; + wine_server_set_reply( req, buffer, buffer_size ); + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + { + struct security_descriptor *sd = (struct security_descriptor *)buffer; + if (reply->sd_len) + { + *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + + sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len; + if (Length >= *ResultLength) + { + psd->Revision = SECURITY_DESCRIPTOR_REVISION; + psd->Sbz1 = 0; + psd->Control = sd->control | SE_SELF_RELATIVE; + psd->Owner = sd->owner_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : 0; + psd->Group = sd->group_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len : 0; + psd->Sacl = sd->sacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len : 0; + psd->Dacl = sd->dacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len + sd->sacl_len : 0; + /* owner, group, sacl and dacl are the same type as in the server + * and in the same order so we copy the memory in one block */ + memcpy((char *)pSecurityDescriptor + sizeof(SECURITY_DESCRIPTOR_RELATIVE), + buffer + sizeof(struct security_descriptor), + sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len); + } + else + status = STATUS_BUFFER_TOO_SMALL; + } + else + { + *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + if (Length >= *ResultLength) + { + memset(psd, 0, sizeof(*psd)); + psd->Revision = SECURITY_DESCRIPTOR_REVISION; + psd->Control = SE_SELF_RELATIVE; + } + else + status = STATUS_BUFFER_TOO_SMALL; + } + } + else if (status == STATUS_BUFFER_TOO_SMALL) + { + buffer_size = reply->sd_len; + need_more_memory = TRUE; + } + } + SERVER_END_REQ; + RtlFreeHeap(GetProcessHeap(), 0, buffer); + } while (need_more_memory); + + return status; } diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c index c49e9b8984e..825a2ab2aad 100644 --- a/dlls/ole32/compositemoniker.c +++ b/dlls/ole32/compositemoniker.c @@ -1813,12 +1813,16 @@ CompositeMonikerImpl_Construct(IMoniker** ppMoniker, if (++This->tabLastIndex==This->tabSize){ + LPVOID tab_moniker = This->tabMoniker; This->tabSize+=BLOCK_TAB_SIZE; This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); - if (This->tabMoniker==NULL) + if (This->tabMoniker==NULL){ + HeapFree(GetProcessHeap(), 0, tab_moniker); + HeapFree(GetProcessHeap(), 0, This); return E_OUTOFMEMORY; + } } } @@ -1862,13 +1866,17 @@ CompositeMonikerImpl_Construct(IMoniker** ppMoniker, /* resize tabMoniker if needed */ if (This->tabLastIndex==This->tabSize){ + LPVOID tab_moniker = This->tabMoniker; This->tabSize+=BLOCK_TAB_SIZE; This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); - if (This->tabMoniker==NULL) - return E_OUTOFMEMORY; + if (This->tabMoniker==NULL){ + HeapFree(GetProcessHeap(), 0, tab_moniker); + HeapFree(GetProcessHeap(), 0, This); + return E_OUTOFMEMORY; + } } } else{ @@ -1901,13 +1909,17 @@ CompositeMonikerImpl_Construct(IMoniker** ppMoniker, } if (This->tabLastIndex==This->tabSize){ + LPVOID tab_moniker = This->tabMoniker; This->tabSize+=BLOCK_TAB_SIZE; This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); - if (This->tabMoniker==NULL) + if (This->tabMoniker==NULL){ + HeapFree(GetProcessHeap(), 0, tab_moniker); + HeapFree(GetProcessHeap(), 0, This); return E_OUTOFMEMORY; + } } } diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c index 1a30aa371b2..4a5ad89649c 100644 --- a/dlls/oleaut32/tmarshal.c +++ b/dlls/oleaut32/tmarshal.c @@ -967,6 +967,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR)); if (hres) { ERR("Failed to read BSTR.\n"); + HeapFree(GetProcessHeap(),0,str); return hres; } *bstr = CoTaskMemAlloc(sizeof(BSTR *)); @@ -997,6 +998,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR)); if (hres) { ERR("Failed to read BSTR.\n"); + HeapFree(GetProcessHeap(),0,str); return hres; } *arg = (DWORD)SysAllocStringLen(str,len); diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index b14b5cf3507..276fe816371 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -215,11 +215,6 @@ sub GenerateThunk($$$$$) return "" if $func_ref->[0] eq "glGetString"; return "" if $func_ref->[0] eq "glGetIntegerv"; - return "" if $func_ref->[0] eq "glEnable"; - return "" if $func_ref->[0] eq "glIsEnabled"; - return "" if $func_ref->[0] eq "glDisable"; - return "" if $func_ref->[0] eq "glScissor"; - return "" if $func_ref->[0] eq "glViewport"; return "" if $func_ref->[0] eq "glFinish"; return "" if $func_ref->[0] eq "glFlush"; diff --git a/dlls/opengl32/opengl_norm.c b/dlls/opengl32/opengl_norm.c index 69acc854201..fcd4be49c5b 100644 --- a/dlls/opengl32/opengl_norm.c +++ b/dlls/opengl32/opengl_norm.c @@ -810,6 +810,16 @@ void WINAPI wine_glDepthRange( GLclampd nearParam, GLclampd farParam ) { } /*********************************************************************** + * glDisable (OPENGL32.@) + */ +void WINAPI wine_glDisable( GLenum cap ) { + TRACE("(%d)\n", cap ); + ENTER_GL(); + glDisable( cap ); + LEAVE_GL(); +} + +/*********************************************************************** * glDisableClientState (OPENGL32.@) */ void WINAPI wine_glDisableClientState( GLenum array ) { @@ -900,6 +910,16 @@ void WINAPI wine_glEdgeFlagv( GLboolean* flag ) { } /*********************************************************************** + * glEnable (OPENGL32.@) + */ +void WINAPI wine_glEnable( GLenum cap ) { + TRACE("(%d)\n", cap ); + ENTER_GL(); + glEnable( cap ); + LEAVE_GL(); +} + +/*********************************************************************** * glEnableClientState (OPENGL32.@) */ void WINAPI wine_glEnableClientState( GLenum array ) { @@ -1704,6 +1724,18 @@ void WINAPI wine_glInterleavedArrays( GLenum format, GLsizei stride, GLvoid* poi } /*********************************************************************** + * glIsEnabled (OPENGL32.@) + */ +GLboolean WINAPI wine_glIsEnabled( GLenum cap ) { + GLboolean ret_value; + TRACE("(%d)\n", cap ); + ENTER_GL(); + ret_value = glIsEnabled( cap ); + LEAVE_GL(); + return ret_value; +} + +/*********************************************************************** * glIsList (OPENGL32.@) */ GLboolean WINAPI wine_glIsList( GLuint list ) { @@ -2810,6 +2842,16 @@ void WINAPI wine_glScalef( GLfloat x, GLfloat y, GLfloat z ) { } /*********************************************************************** + * glScissor (OPENGL32.@) + */ +void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) { + TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); + ENTER_GL(); + glScissor( x, y, width, height ); + LEAVE_GL(); +} + +/*********************************************************************** * glSelectBuffer (OPENGL32.@) */ void WINAPI wine_glSelectBuffer( GLsizei size, GLuint* buffer ) { @@ -3668,3 +3710,13 @@ void WINAPI wine_glVertexPointer( GLint size, GLenum type, GLsizei stride, GLvoi glVertexPointer( size, type, stride, pointer ); LEAVE_GL(); } + +/*********************************************************************** + * glViewport (OPENGL32.@) + */ +void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) { + TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); + ENTER_GL(); + glViewport( x, y, width, height ); + LEAVE_GL(); +} diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index deac8dbc118..ec91cfe9dfd 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -48,12 +48,7 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl); typedef struct wine_wgl_s { PROC WINAPI (*p_wglGetProcAddress)(LPCSTR lpszProc); - void WINAPI (*p_wglDisable)(GLenum cap); - void WINAPI (*p_wglEnable)(GLenum cap); void WINAPI (*p_wglGetIntegerv)(GLenum pname, GLint* params); - GLboolean WINAPI (*p_wglIsEnabled)(GLenum cap); - void WINAPI (*p_wglScissor)(GLint x, GLint y, GLsizei width, GLsizei height); - void WINAPI (*p_wglViewport)(GLint x, GLint y, GLsizei width, GLsizei height); void WINAPI (*p_wglFinish)(void); void WINAPI (*p_wglFlush)(void); } wine_wgl_t; @@ -571,51 +566,6 @@ BOOL WINAPI wglUseFontOutlinesW(HDC hdc, } /*********************************************************************** - * glEnable (OPENGL32.@) - */ -void WINAPI wine_glEnable( GLenum cap ) -{ - TRACE("(%d)\n", cap ); - wine_wgl.p_wglEnable(cap); -} - -/*********************************************************************** - * glIsEnabled (OPENGL32.@) - */ -GLboolean WINAPI wine_glIsEnabled( GLenum cap ) -{ - TRACE("(%d)\n", cap ); - return wine_wgl.p_wglIsEnabled(cap); -} - -/*********************************************************************** - * glDisable (OPENGL32.@) - */ -void WINAPI wine_glDisable( GLenum cap ) -{ - TRACE("(%d)\n", cap ); - wine_wgl.p_wglDisable(cap); -} - -/*********************************************************************** - * glScissor (OPENGL32.@) - */ -void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) -{ - TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); - wine_wgl.p_wglScissor(x, y, width, height); -} - -/*********************************************************************** - * glViewport (OPENGL32.@) - */ -void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) -{ - TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); - wine_wgl.p_wglViewport(x, y, width, height); -} - -/*********************************************************************** * glFinish (OPENGL32.@) */ void WINAPI wine_glFinish( void ) @@ -719,12 +669,7 @@ static BOOL process_attach(void) wine_wgl.p_wglGetProcAddress = (void *)GetProcAddress(mod_gdi32, "wglGetProcAddress"); /* Interal WGL function */ - wine_wgl.p_wglDisable = (void *)wine_wgl.p_wglGetProcAddress("wglDisable"); - wine_wgl.p_wglEnable = (void *)wine_wgl.p_wglGetProcAddress("wglEnable"); wine_wgl.p_wglGetIntegerv = (void *)wine_wgl.p_wglGetProcAddress("wglGetIntegerv"); - wine_wgl.p_wglIsEnabled = (void *)wine_wgl.p_wglGetProcAddress("wglIsEnabled"); - wine_wgl.p_wglScissor = (void *)wine_wgl.p_wglGetProcAddress("wglScissor"); - wine_wgl.p_wglViewport = (void *)wine_wgl.p_wglGetProcAddress("wglViewport"); wine_wgl.p_wglFinish = (void *)wine_wgl.p_wglGetProcAddress("wglFinish"); wine_wgl.p_wglFlush = (void *)wine_wgl.p_wglGetProcAddress("wglFlush"); diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c index c5117bf642f..49d0a33137e 100644 --- a/dlls/pdh/pdh_main.c +++ b/dlls/pdh/pdh_main.c @@ -482,7 +482,7 @@ static DWORD CALLBACK collect_query_thread( void *arg ) if (WaitForSingleObject( stop, interval ) != WAIT_TIMEOUT) ExitThread( 0 ); EnterCriticalSection( &pdh_handle_cs ); - if (!query || query->magic != PDH_MAGIC_QUERY) + if (query->magic != PDH_MAGIC_QUERY) { LeaveCriticalSection( &pdh_handle_cs ); ExitThread( PDH_INVALID_HANDLE ); diff --git a/dlls/secur32/ntlm.c b/dlls/secur32/ntlm.c index 79241561eb2..5041892f2de 100644 --- a/dlls/secur32/ntlm.c +++ b/dlls/secur32/ntlm.c @@ -380,6 +380,26 @@ static int ntlm_GetTokenBufferIndex(PSecBufferDesc pMessage) return -1; } +/************************************************************************* + * ntlm_GetDataBufferIndex + * Calculates the index of the first secbuffer with BufferType == SECBUFFER_DATA + * Returns index if found or -1 if not found. + */ +static int ntlm_GetDataBufferIndex(PSecBufferDesc pMessage) +{ + UINT i; + + TRACE("%p\n", pMessage); + + for( i = 0; i < pMessage->cBuffers; ++i ) + { + if(pMessage->pBuffers[i].BufferType == SECBUFFER_DATA) + return i; + } + + return -1; +} + /*********************************************************************** * InitializeSecurityContextW */ @@ -1609,7 +1629,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { PNegoHelper helper; - int token_idx; + int token_idx, data_idx; TRACE("(%p %d %p %d)\n", phContext, fQOP, pMessage, MessageSeqNo); @@ -1628,6 +1648,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1) return SEC_E_INVALID_TOKEN; + if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1 ) + return SEC_E_INVALID_TOKEN; + if(pMessage->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL; @@ -1638,8 +1661,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, { ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE); SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, - (BYTE *)pMessage->pBuffers[1].pvBuffer, - pMessage->pBuffers[1].cbBuffer); + (BYTE *)pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); if(helper->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCHANGE) SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, @@ -1662,8 +1685,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, sig = pMessage->pBuffers[token_idx].pvBuffer; - SECUR32_arc4Process(helper->crypt.ntlm.a4i, pMessage->pBuffers[1].pvBuffer, - pMessage->pBuffers[1].cbBuffer); + SECUR32_arc4Process(helper->crypt.ntlm.a4i, + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12); if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0) @@ -1683,7 +1707,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, SECURITY_STATUS ret; ULONG ntlmssp_flags_save; PNegoHelper helper; - int token_idx; + int token_idx, data_idx; TRACE("(%p %p %d %p)\n", phContext, pMessage, MessageSeqNo, pfQOP); if(!phContext) @@ -1698,6 +1722,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1) return SEC_E_INVALID_TOKEN; + if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1) + return SEC_E_INVALID_TOKEN; + if(pMessage->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL; @@ -1706,12 +1733,14 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 && helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i, - pMessage->pBuffers[1].pvBuffer, pMessage->pBuffers[1].cbBuffer); + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); } else { SECUR32_arc4Process(helper->crypt.ntlm.a4i, - pMessage->pBuffers[1].pvBuffer, pMessage->pBuffers[1].cbBuffer); + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); } /* Make sure we use a session key for the signature check, EncryptMessage diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 2459ccdadd0..0ec77b9e8ac 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -1986,7 +1986,7 @@ static void SETUPDI_EnumerateInterfaces(HDEVINFO DeviceInfoSet, static void SETUPDI_EnumerateMatchingDevices(HDEVINFO DeviceInfoSet, LPCWSTR parent, HKEY key, const GUID *class, DWORD flags) { - struct DeviceInfoSet *set = (struct DeviceInfoSet *)set; + struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; DWORD i, len; WCHAR subKeyName[MAX_PATH]; LONG l = ERROR_SUCCESS; diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index b1cb585a617..d3e5825b2ab 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -529,9 +529,15 @@ HRESULT WINAPI GetAcceptLanguagesA( LPSTR langbuf, LPDWORD buflen) langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW); retval = GetAcceptLanguagesW(langbufW, &buflenW); - /* FIXME: this is wrong, the string may not be null-terminated */ - convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, - *buflen, NULL, NULL); + if (retval == S_OK) + { + convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, *buflen, NULL, NULL); + } + else /* copy partial string anyway */ + { + convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, *buflen, langbuf, *buflen, NULL, NULL); + if (convlen < *buflen) langbuf[convlen] = 0; + } *buflen = buflenW ? convlen : 0; HeapFree(GetProcessHeap(), 0, langbufW); diff --git a/dlls/urlmon/bindctx.c b/dlls/urlmon/bindctx.c index 3d241a6e6c6..9d24707d2a6 100644 --- a/dlls/urlmon/bindctx.c +++ b/dlls/urlmon/bindctx.c @@ -36,6 +36,551 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); +static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; + +extern IID IID_IBindStatusCallbackHolder; + +typedef struct { + const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl; + const IServiceProviderVtbl *lpServiceProviderVtbl; + const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl; + const IAuthenticateVtbl *lpAuthenticateVtbl; + + LONG ref; + + IBindStatusCallback *callback; + IServiceProvider *serv_prov; + + IHttpNegotiate *http_negotiate; + BOOL init_http_negotiate; + IHttpNegotiate2 *http_negotiate2; + BOOL init_http_negotiate2; + IAuthenticate *authenticate; + BOOL init_authenticate; +} BindStatusCallback; + +#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl) +#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) +#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl) +#define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl) + +#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface) + +static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) { + TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) { + TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv); + *ppv = This; + }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { + TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv); + *ppv = SERVPROV(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { + TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv); + *ppv = AUTHENTICATE(This); + } + + if(*ppv) { + IBindStatusCallback_AddRef((IUnknown*)*ppv); + return S_OK; + } + + TRACE("Unsupported riid = %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + return ref; +} + +static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + if(!ref) { + if(This->serv_prov) + IServiceProvider_Release(This->serv_prov); + if(This->http_negotiate) + IHttpNegotiate_Release(This->http_negotiate); + if(This->http_negotiate2) + IHttpNegotiate2_Release(This->http_negotiate2); + if(This->authenticate) + IAuthenticate_Release(This->authenticate); + IBindStatusCallback_Release(This->callback); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, + DWORD dwReserved, IBinding *pbind) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); + + return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind); +} + +static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pnPriority); + + return IBindStatusCallback_GetPriority(This->callback, pnPriority); +} + +static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d)\n", This, reserved); + + return IBindStatusCallback_OnLowResource(This->callback, reserved); +} + +static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, + ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, + debugstr_w(szStatusText)); + + return IBindStatusCallback_OnProgress(This->callback, ulProgress, + ulProgressMax, ulStatusCode, szStatusText); +} + +static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, + HRESULT hresult, LPCWSTR szError) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); + + return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); +} + +static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, + DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); + + return IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo); +} + +static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, + DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); + + return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed); +} + +static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, + REFIID riid, IUnknown *punk) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk); + + return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk); +} + +#undef STATUSCLB_THIS + +static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { + BindStatusCallback_QueryInterface, + BindStatusCallback_AddRef, + BindStatusCallback_Release, + BindStatusCallback_OnStartBinding, + BindStatusCallback_GetPriority, + BindStatusCallback_OnLowResource, + BindStatusCallback_OnProgress, + BindStatusCallback_OnStopBinding, + BindStatusCallback_GetBindInfo, + BindStatusCallback_OnDataAvailable, + BindStatusCallback_OnObjectAvailable +}; + +#define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface) + +static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface, + REFGUID guidService, REFIID riid, void **ppv) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + HRESULT hres; + + if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) { + TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_http_negotiate) { + This->init_http_negotiate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate, + (void**)&This->http_negotiate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate, + &IID_IHttpNegotiate, (void**)&This->http_negotiate); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { + TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_http_negotiate2) { + This->init_http_negotiate2 = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate2, + (void**)&This->http_negotiate2); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate2, + &IID_IHttpNegotiate2, (void**)&This->http_negotiate2); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IAuthenticate, guidService)) { + TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_authenticate) { + This->init_authenticate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IAuthenticate, + (void**)&This->authenticate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IAuthenticate, + &IID_IAuthenticate, (void**)&This->authenticate); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); + + hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); + if(SUCCEEDED(hres)) + return S_OK; + + if(This->serv_prov) { + hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv); + if(SUCCEEDED(hres)) + return S_OK; + } + + return E_NOINTERFACE; +} + +#undef SERVPROV_THIS + +static const IServiceProviderVtbl BSCServiceProviderVtbl = { + BSCServiceProvider_QueryInterface, + BSCServiceProvider_AddRef, + BSCServiceProvider_Release, + BSCServiceProvider_QueryService +}; + +#define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface) + +static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, + LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, + pszAdditionalHeaders); + + *pszAdditionalHeaders = NULL; + + if(!This->http_negotiate) + return S_OK; + + return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders, + dwReserved, pszAdditionalHeaders); +} + +static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode, + LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, + LPWSTR *pszAdditionalRequestHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + LPWSTR additional_headers = NULL; + HRESULT hres = S_OK; + + TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), + debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); + + if(This->http_negotiate) + hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders, + szRequestHeaders, &additional_headers); + + if(pszAdditionalRequestHeaders) + *pszAdditionalRequestHeaders = additional_headers; + else if(additional_headers) + CoTaskMemFree(additional_headers); + + return hres; +} + +static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface, + BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved); + + if(!This->http_negotiate2) + return E_FAIL; + + return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId, + pcbSecurityId, dwReserved); +} + +#undef HTTPNEG2_THIS + +static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = { + BSCHttpNegotiate_QueryInterface, + BSCHttpNegotiate_AddRef, + BSCHttpNegotiate_Release, + BSCHttpNegotiate_BeginningTransaction, + BSCHttpNegotiate_OnResponse, + BSCHttpNegotiate_GetRootSecurityId +}; + +#define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface) + +static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv); +} + +static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface, + HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword); + return E_NOTIMPL; +} + +#undef AUTHENTICATE_THIS + +static const IAuthenticateVtbl BSCAuthenticateVtbl = { + BSCAuthenticate_QueryInterface, + BSCAuthenticate_AddRef, + BSCAuthenticate_Release, + BSCAuthenticate_Authenticate +}; + +static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc) +{ + BindStatusCallback *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BindStatusCallback)); + + ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; + ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl; + ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl; + ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl; + + ret->ref = 1; + + IBindStatusCallback_AddRef(bsc); + ret->callback = bsc; + + IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&ret->serv_prov); + + return STATUSCLB(ret); +} + +/*********************************************************************** + * RegisterBindStatusCallback (urlmon.@) + * + * Register a bind status callback. + * + * PARAMS + * pbc [I] Binding context + * pbsc [I] Callback to register + * ppbscPrevious [O] Destination for previous callback + * dwReserved [I] Reserved, must be 0. + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any argument is invalid, or + * E_OUTOFMEMORY if memory allocation fails. + */ +HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, + IBindStatusCallback **ppbscPrevious, DWORD dwReserved) +{ + BindStatusCallback *holder; + IBindStatusCallback *bsc, *prev = NULL; + IUnknown *unk; + HRESULT hres; + + TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved); + + if (!pbc || !pbsc) + return E_INVALIDARG; + + hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); + if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc); + if(SUCCEEDED(hres)) { + hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); + if(SUCCEEDED(hres)) { + prev = holder->callback; + IBindStatusCallback_AddRef(prev); + IBindStatusCallback_Release(bsc); + IBindStatusCallback_Release(STATUSCLB(holder)); + }else { + prev = bsc; + } + } + + IUnknown_Release(unk); + IBindCtx_RevokeObjectParam(pbc, BSCBHolder); + } + + hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)create_bsc(pbsc)); + if(FAILED(hres)) { + IBindStatusCallback_Release(prev); + return hres; + } + + if(ppbscPrevious) + *ppbscPrevious = prev; + return S_OK; +} + +/*********************************************************************** + * RevokeBindStatusCallback (URLMON.@) + * + * Unregister a bind status callback. + * + * pbc [I] Binding context + * pbsc [I] Callback to unregister + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any argument is invalid + */ +HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc) +{ + BindStatusCallback *holder; + IBindStatusCallback *callback; + IUnknown *unk; + BOOL dorevoke = FALSE; + HRESULT hres; + + TRACE("(%p %p)\n", pbc, pbsc); + + if (!pbc || !pbsc) + return E_INVALIDARG; + + hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); + if(FAILED(hres)) + return S_OK; + + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback); + IUnknown_Release(unk); + if(FAILED(hres)) + return S_OK; + + hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder); + if(SUCCEEDED(hres)) { + if(pbsc == holder->callback) + dorevoke = TRUE; + IBindStatusCallback_Release(STATUSCLB(holder)); + }else if(pbsc == callback) { + dorevoke = TRUE; + } + IBindStatusCallback_Release(callback); + + if(dorevoke) + IBindCtx_RevokeObjectParam(pbc, BSCBHolder); + + return S_OK; +} + typedef struct { const IBindCtxVtbl *lpBindCtxVtbl; diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 894d7b5accc..eb48bfadf06 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -46,15 +46,6 @@ typedef struct _task_header_t { } task_header_t; typedef struct { - const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl; - - LONG ref; - - IHttpNegotiate *http_negotiate; - IHttpNegotiate2 *http_negotiate2; -} HttpNegotiate2Wrapper; - -typedef struct { const IStreamVtbl *lpStreamVtbl; LONG ref; @@ -85,7 +76,6 @@ struct Binding { IInternetProtocol *protocol; IServiceProvider *service_provider; ProtocolStream *stream; - HttpNegotiate2Wrapper *httpneg2_wrapper; BINDINFO bindinfo; DWORD bindf; @@ -261,154 +251,6 @@ static void dump_BINDINFO(BINDINFO *bi) ); } -#define HTTPNEG2_THIS(iface) DEFINE_THIS(HttpNegotiate2Wrapper, HttpNegotiate2, iface) - -static HRESULT WINAPI HttpNegotiate2Wrapper_QueryInterface(IHttpNegotiate2 *iface, - REFIID riid, void **ppv) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - *ppv = NULL; - - if(IsEqualGUID(&IID_IUnknown, riid)) { - TRACE("(IID_IUnknown %p)\n", ppv); - *ppv = HTTPNEG2(This); - }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { - TRACE("(IID_IHttpNegotiate %p)\n", ppv); - *ppv = HTTPNEG2(This); - }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) { - TRACE("(IID_IHttpNegotiate2 %p)\n", ppv); - *ppv = HTTPNEG2(This); - } - - if(*ppv) { - IHttpNegotiate2_AddRef(HTTPNEG2(This)); - return S_OK; - } - - WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); - return E_NOINTERFACE; -} - -static ULONG WINAPI HttpNegotiate2Wrapper_AddRef(IHttpNegotiate2 *iface) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - return ref; -} - -static ULONG WINAPI HttpNegotiate2Wrapper_Release(IHttpNegotiate2 *iface) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - if(!ref) { - if (This->http_negotiate) - IHttpNegotiate_Release(This->http_negotiate); - if (This->http_negotiate2) - IHttpNegotiate2_Release(This->http_negotiate2); - HeapFree(GetProcessHeap(), 0, This); - - URLMON_UnlockModule(); - } - - return ref; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_BeginningTransaction(IHttpNegotiate2 *iface, - LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, - pszAdditionalHeaders); - - if(This->http_negotiate) - return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders, - dwReserved, pszAdditionalHeaders); - - *pszAdditionalHeaders = NULL; - return S_OK; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode, - LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, - LPWSTR *pszAdditionalRequestHeaders) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - LPWSTR szAdditionalRequestHeaders = NULL; - HRESULT hres = S_OK; - - TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), - debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); - - /* IHttpNegotiate2_OnResponse expects pszAdditionalHeaders to be non-NULL when it is - * implemented as part of IBindStatusCallback, but it is NULL when called directly from - * IProtocol */ - if(!pszAdditionalRequestHeaders) - pszAdditionalRequestHeaders = &szAdditionalRequestHeaders; - - if(This->http_negotiate) - { - hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders, - szRequestHeaders, pszAdditionalRequestHeaders); - if(pszAdditionalRequestHeaders == &szAdditionalRequestHeaders && - szAdditionalRequestHeaders) - CoTaskMemFree(szAdditionalRequestHeaders); - } - else - { - *pszAdditionalRequestHeaders = NULL; - } - - return hres; -} - -static HRESULT WINAPI HttpNegotiate2Wrapper_GetRootSecurityId(IHttpNegotiate2 *iface, - BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) -{ - HttpNegotiate2Wrapper *This = HTTPNEG2_THIS(iface); - - TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved); - - if (This->http_negotiate2) - return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId, - pcbSecurityId, dwReserved); - - /* That's all we have to do here */ - return E_FAIL; -} - -#undef HTTPNEG2_THIS - -static const IHttpNegotiate2Vtbl HttpNegotiate2WrapperVtbl = { - HttpNegotiate2Wrapper_QueryInterface, - HttpNegotiate2Wrapper_AddRef, - HttpNegotiate2Wrapper_Release, - HttpNegotiate2Wrapper_BeginningTransaction, - HttpNegotiate2Wrapper_OnResponse, - HttpNegotiate2Wrapper_GetRootSecurityId -}; - -static HttpNegotiate2Wrapper *create_httpneg2_wrapper(void) -{ - HttpNegotiate2Wrapper *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HttpNegotiate2Wrapper)); - - ret->lpHttpNegotiate2Vtbl = &HttpNegotiate2WrapperVtbl; - ret->ref = 1; - ret->http_negotiate = NULL; - ret->http_negotiate2 = NULL; - - URLMON_LockModule(); - - return ret; -} - #define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface) static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface, @@ -685,8 +527,6 @@ static ULONG WINAPI Binding_Release(IBinding *iface) IServiceProvider_Release(This->service_provider); if(This->stream) IStream_Release(STREAM(This->stream)); - if(This->httpneg2_wrapper) - IHttpNegotiate2_Release(HTTPNEG2(This->httpneg2_wrapper)); ReleaseBindInfo(&This->bindinfo); This->section.DebugInfo->Spare[0] = 0; @@ -1180,22 +1020,6 @@ static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, return hres; } - if(IsEqualGUID(&IID_IHttpNegotiate, guidService) - || IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { - if(!This->httpneg2_wrapper) { - WARN("HttpNegotiate2Wrapper expected to be non-NULL\n"); - } else { - if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) - IBindStatusCallback_QueryInterface(This->callback, riid, - (void **)&This->httpneg2_wrapper->http_negotiate); - else - IBindStatusCallback_QueryInterface(This->callback, riid, - (void **)&This->httpneg2_wrapper->http_negotiate2); - - return IHttpNegotiate2_QueryInterface(HTTPNEG2(This->httpneg2_wrapper), riid, ppv); - } - } - WARN("unknown service %s\n", debugstr_guid(guidService)); return E_NOTIMPL; } @@ -1309,7 +1133,6 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * ret->protocol = NULL; ret->service_provider = NULL; ret->stream = NULL; - ret->httpneg2_wrapper = NULL; ret->mime = NULL; ret->url = NULL; ret->apartment_thread = GetCurrentThreadId(); @@ -1367,8 +1190,6 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding * ret->stgmed.u.pstm = STREAM(ret->stream); ret->stgmed.pUnkForRelease = (IUnknown*)BINDING(ret); /* NOTE: Windows uses other IUnknown */ - ret->httpneg2_wrapper = create_httpneg2_wrapper(); - *binding = ret; return S_OK; } diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 57126692edf..da57ce84f5f 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -20,6 +20,7 @@ */ #include +#include #define COBJMACROS #define CONST_VTABLE @@ -67,6 +68,13 @@ DEFINE_EXPECT(QueryInterface_IServiceProvider); DEFINE_EXPECT(QueryInterface_IHttpNegotiate); +DEFINE_EXPECT(QueryInterface_IBindStatusCallback); +DEFINE_EXPECT(QueryInterface_IBindStatusCallbackHolder); +DEFINE_EXPECT(QueryInterface_IInternetBindInfo); +DEFINE_EXPECT(QueryInterface_IAuthenticate); +DEFINE_EXPECT(QueryInterface_IInternetProtocol); +DEFINE_EXPECT(QueryService_IAuthenticate); +DEFINE_EXPECT(QueryService_IInternetProtocol); DEFINE_EXPECT(BeginningTransaction); DEFINE_EXPECT(OnResponse); DEFINE_EXPECT(QueryInterface_IHttpNegotiate2); @@ -104,7 +112,7 @@ static const WCHAR ITS_URL[] = static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':', 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0}; - +static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0}; @@ -113,6 +121,8 @@ static BOOL stopped_binding = FALSE, emulate_protocol = FALSE, static DWORD read = 0, bindf = 0; static CHAR mime_type[512]; +extern IID IID_IBindStatusCallbackHolder; + static LPCWSTR urls[] = { WINE_ABOUT_URL, ABOUT_BLANK, @@ -135,6 +145,18 @@ static enum { END_DOWNLOAD } download_state; +static const char *debugstr_guid(REFIID riid) +{ + static char buf[50]; + + sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], + riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], + riid->Data4[5], riid->Data4[6], riid->Data4[7]); + + return buf; +} + static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2) { HRESULT hr; @@ -453,6 +475,9 @@ static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface, ok(pbSecurityId != NULL, "pbSecurityId == NULL\n"); ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n"); + if(pbSecurityId == (void*)0xdeadbeef) + return E_NOTIMPL; + if(pcbSecurityId) { ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId); *pcbSecurityId = sizeof(sec_id); @@ -475,9 +500,52 @@ static IHttpNegotiate2Vtbl HttpNegotiateVtbl = { static IHttpNegotiate2 HttpNegotiate = { &HttpNegotiateVtbl }; +static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) +{ + ok(0, "unexpected call\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface) +{ + return 2; +} + +static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface) +{ + return 1; +} + +static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, + REFGUID guidService, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IAuthenticate, guidService)) { + CHECK_EXPECT(QueryService_IAuthenticate); + return E_NOTIMPL; + } + + if(IsEqualGUID(&IID_IInternetProtocol, guidService)) { + CHECK_EXPECT2(QueryService_IInternetProtocol); + return E_NOTIMPL; + } + + ok(0, "unexpected service %s\n", debugstr_guid(guidService)); + return E_NOINTERFACE; +} + +static IServiceProviderVtbl ServiceProviderVtbl = { + ServiceProvider_QueryInterface, + ServiceProvider_AddRef, + ServiceProvider_Release, + ServiceProvider_QueryService +}; + +static IServiceProvider ServiceProvider = { &ServiceProviderVtbl }; + static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_IInternetProtocol, riid)) { + CHECK_EXPECT2(QueryInterface_IInternetProtocol); if(emulate_protocol) { *ppv = &Protocol; return S_OK; @@ -487,7 +555,9 @@ static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFII } else if (IsEqualGUID(&IID_IServiceProvider, riid)) { - CHECK_EXPECT(QueryInterface_IServiceProvider); + CHECK_EXPECT2(QueryInterface_IServiceProvider); + *ppv = &ServiceProvider; + return S_OK; } else if (IsEqualGUID(&IID_IHttpNegotiate, riid)) { @@ -501,6 +571,31 @@ static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFII *ppv = &HttpNegotiate; return S_OK; } + else if (IsEqualGUID(&IID_IAuthenticate, riid)) + { + CHECK_EXPECT(QueryInterface_IAuthenticate); + return E_NOINTERFACE; + } + else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) + { + CHECK_EXPECT2(QueryInterface_IBindStatusCallback); + *ppv = iface; + return S_OK; + } + else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) + { + CHECK_EXPECT2(QueryInterface_IBindStatusCallbackHolder); + return E_NOINTERFACE; + } + else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) + { + /* TODO */ + CHECK_EXPECT(QueryInterface_IInternetBindInfo); + } + else + { + ok(0, "unexpected interface %s\n", debugstr_guid(riid)); + } return E_NOINTERFACE; } @@ -524,6 +619,10 @@ static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD CHECK_EXPECT(OnStartBinding); ok(pib != NULL, "pib should not be NULL\n"); + ok(dwReserved == 0xff, "dwReserved=%x\n", dwReserved); + + if(pib == (void*)0xdeadbeef) + return S_OK; hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon); ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n"); @@ -713,8 +812,8 @@ static void test_CreateAsyncBindCtx(void) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx); - ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n", hres); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n", hres); + CHECK_CALLED(QueryInterface_IServiceProvider); bindopts.cbStruct = sizeof(bindopts); hres = IBindCtx_GetBindOptions(bctx, &bindopts); @@ -788,7 +887,7 @@ static void test_CreateAsyncBindCtxEx(void) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtxEx(NULL, 0, &bsc, NULL, &bctx, 0); ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + CHECK_CALLED(QueryInterface_IServiceProvider); hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk); ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres); @@ -799,6 +898,198 @@ static void test_CreateAsyncBindCtxEx(void) IBindCtx_Release(bctx); } +static void test_bscholder(IBindStatusCallback *holder) +{ + IServiceProvider *serv_prov; + IHttpNegotiate *http_negotiate, *http_negotiate_serv; + IHttpNegotiate2 *http_negotiate2, *http_negotiate2_serv; + IAuthenticate *authenticate, *authenticate_serv; + IInternetProtocol *protocol; + BINDINFO bindinfo = {sizeof(bindinfo)}; + LPWSTR wstr; + DWORD dw; + HRESULT hres; + + static const WCHAR emptyW[] = {0}; + + hres = IBindStatusCallback_QueryInterface(holder, &IID_IServiceProvider, (void**)&serv_prov); + ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres); + + dw = 0xdeadbeef; + SET_EXPECT(GetBindInfo); + hres = IBindStatusCallback_GetBindInfo(holder, &dw, &bindinfo); + ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres); + CHECK_CALLED(GetBindInfo); + + SET_EXPECT(OnStartBinding); + hres = IBindStatusCallback_OnStartBinding(holder, 0, (void*)0xdeadbeef); + ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres); + CHECK_CALLED(OnStartBinding); + + hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate, (void**)&http_negotiate); + ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres); + + wstr = (void*)0xdeadbeef; + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, urls[test_protocol], (void*)0xdeadbeef, 0xff, &wstr); + ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); + ok(wstr == NULL, "wstr = %p\n", wstr); + + SET_EXPECT(QueryInterface_IHttpNegotiate); + hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate, + (void**)&http_negotiate_serv); + ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres); + CHECK_CALLED(QueryInterface_IHttpNegotiate); + + ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n"); + + wstr = (void*)0xdeadbeef; + SET_EXPECT(BeginningTransaction); + hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, urls[test_protocol], emptyW, 0, &wstr); + CHECK_CALLED(BeginningTransaction); + ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); + ok(wstr == NULL, "wstr = %p\n", wstr); + + IHttpNegotiate_Release(http_negotiate_serv); + + hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate, + (void**)&http_negotiate_serv); + ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres); + ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n"); + IHttpNegotiate_Release(http_negotiate_serv); + + hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate2, (void**)&http_negotiate2); + ok(hres == S_OK, "Could not get IHttpNegotiate2 interface: %08x\n", hres); + + hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0); + ok(hres == E_FAIL, "GetRootSecurityId failed: %08x\n", hres); + + IHttpNegotiate_Release(http_negotiate2); + + SET_EXPECT(QueryInterface_IHttpNegotiate2); + hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2, + (void**)&http_negotiate2_serv); + ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres); + CHECK_CALLED(QueryInterface_IHttpNegotiate2); + ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n"); + + SET_EXPECT(GetRootSecurityId); + hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0); + ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres); + CHECK_CALLED(GetRootSecurityId); + + IHttpNegotiate_Release(http_negotiate2_serv); + + SET_EXPECT(OnProgress_FINDINGRESOURCE); + hres = IBindStatusCallback_OnProgress(holder, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL); + ok(hres == S_OK, "OnProgress failed: %08x\n", hres); + CHECK_CALLED(OnProgress_FINDINGRESOURCE); + + SET_EXPECT(OnResponse); + wstr = (void*)0xdeadbeef; + hres = IHttpNegotiate_OnResponse(http_negotiate, 200, emptyW, NULL, NULL); + ok(hres == S_OK, "OnResponse failed: %08x\n", hres); + CHECK_CALLED(OnResponse); + + IHttpNegotiate_Release(http_negotiate); + + hres = IBindStatusCallback_QueryInterface(holder, &IID_IAuthenticate, (void**)&authenticate); + ok(hres == S_OK, "Could not get IAuthenticate interface: %08x\n", hres); + + SET_EXPECT(QueryInterface_IAuthenticate); + SET_EXPECT(QueryService_IAuthenticate); + hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate, + (void**)&authenticate_serv); + ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres); + CHECK_CALLED(QueryInterface_IAuthenticate); + CHECK_CALLED(QueryService_IAuthenticate); + ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n"); + IAuthenticate_Release(authenticate_serv); + + hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate, + (void**)&authenticate_serv); + ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres); + ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n"); + + IAuthenticate_Release(authenticate); + IAuthenticate_Release(authenticate_serv); + + SET_EXPECT(OnStopBinding); + hres = IBindStatusCallback_OnStopBinding(holder, S_OK, NULL); + ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres); + CHECK_CALLED(OnStopBinding); + + SET_EXPECT(QueryInterface_IInternetProtocol); + SET_EXPECT(QueryService_IInternetProtocol); + hres = IServiceProvider_QueryService(serv_prov, &IID_IInternetProtocol, &IID_IInternetProtocol, + (void**)&protocol); + ok(hres == E_NOINTERFACE, "QueryService(IInternetProtocol) failed: %08x\n", hres); + CHECK_CALLED(QueryInterface_IInternetProtocol); + CHECK_CALLED(QueryService_IInternetProtocol); + + IServiceProvider_Release(serv_prov); +} + +static void test_RegisterBindStatusCallback(void) +{ + IBindStatusCallback *prevbsc, *clb; + IBindCtx *bindctx; + IUnknown *unk; + HRESULT hres; + + hres = CreateBindCtx(0, &bindctx); + ok(hres == S_OK, "BindCtx failed: %08x\n", hres); + + SET_EXPECT(QueryInterface_IServiceProvider); + + hres = IBindCtx_RegisterObjectParam(bindctx, BSCBHolder, (IUnknown*)&bsc); + ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres); + + SET_EXPECT(QueryInterface_IBindStatusCallback); + SET_EXPECT(QueryInterface_IBindStatusCallbackHolder); + prevbsc = (void*)0xdeadbeef; + hres = RegisterBindStatusCallback(bindctx, &bsc, &prevbsc, 0); + ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres); + ok(prevbsc == &bsc, "prevbsc=%p\n", prevbsc); + CHECK_CALLED(QueryInterface_IBindStatusCallback); + CHECK_CALLED(QueryInterface_IBindStatusCallbackHolder); + + CHECK_CALLED(QueryInterface_IServiceProvider); + + hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk); + ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres); + + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb); + IUnknown_Release(unk); + ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres); + ok(clb != &bsc, "bsc == clb\n"); + + test_bscholder(clb); + + IBindStatusCallback_Release(clb); + + hres = RevokeBindStatusCallback(bindctx, &bsc); + ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres); + + unk = (void*)0xdeadbeef; + hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk); + ok(hres == E_FAIL, "GetObjectParam failed: %08x\n", hres); + ok(unk == NULL, "unk != NULL\n"); + + if(unk) + IUnknown_Release(unk); + + hres = RevokeBindStatusCallback(bindctx, (void*)0xdeadbeef); + ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres); + + hres = RevokeBindStatusCallback(NULL, (void*)0xdeadbeef); + ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres); + + hres = RevokeBindStatusCallback(bindctx, NULL); + ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres); + + IBindCtx_Release(bindctx); +} + static void test_BindToStorage(int protocol, BOOL emul) { IMoniker *mon; @@ -819,16 +1110,16 @@ static void test_BindToStorage(int protocol, BOOL emul) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx); - ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres); + ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres); + CHECK_CALLED(QueryInterface_IServiceProvider); if(FAILED(hres)) return; - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); SET_EXPECT(QueryInterface_IServiceProvider); hres = RegisterBindStatusCallback(bctx, &bsc, &previousclb, 0); - ok(SUCCEEDED(hres), "RegisterBindStatusCallback failed: %08x\n", hres); + ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres); ok(previousclb == &bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + CHECK_CALLED(QueryInterface_IServiceProvider); if(previousclb) IBindStatusCallback_Release(previousclb); @@ -851,8 +1142,10 @@ static void test_BindToStorage(int protocol, BOOL emul) ok(hres == S_OK, "GetDisplayName failed %08x\n", hres); ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n"); - SET_EXPECT(QueryInterface_IServiceProvider); SET_EXPECT(GetBindInfo); + SET_EXPECT(QueryInterface_IInternetProtocol); + if(!emulate_protocol) + SET_EXPECT(QueryService_IInternetProtocol); SET_EXPECT(OnStartBinding); if(emulate_protocol) { SET_EXPECT(Start); @@ -903,8 +1196,10 @@ static void test_BindToStorage(int protocol, BOOL emul) DispatchMessage(&msg); } - todo_wine CHECK_NOT_CALLED(QueryInterface_IServiceProvider); CHECK_CALLED(GetBindInfo); + CHECK_CALLED(QueryInterface_IInternetProtocol); + if(!emulate_protocol) + CHECK_CALLED(QueryService_IInternetProtocol); CHECK_CALLED(OnStartBinding); if(emulate_protocol) { CHECK_CALLED(Start); @@ -1006,6 +1301,7 @@ START_TEST(url) test_create(); test_CreateAsyncBindCtx(); test_CreateAsyncBindCtxEx(); + test_RegisterBindStatusCallback(); trace("synchronous http test...\n"); test_BindToStorage(HTTP_TEST, FALSE); diff --git a/dlls/urlmon/umon.c b/dlls/urlmon/umon.c index db42f7eac8c..9d17afa97e8 100644 --- a/dlls/urlmon/umon.c +++ b/dlls/urlmon/umon.c @@ -738,7 +738,7 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, sizeof(schema)/sizeof(WCHAR), 0, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; if(pmkToLeft) - FIXME("Unsupported pmkToLeft\n"); + FIXME("Unsupported pmkToLeft\n"); bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url); if(!bret) { @@ -1209,85 +1209,6 @@ HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback } /*********************************************************************** - * RegisterBindStatusCallback (URLMON.@) - * - * Register a bind status callback. - * - * PARAMS - * pbc [I] Binding context - * pbsc [I] Callback to register - * ppbscPrevious [O] Destination for previous callback - * dwReserved [I] Reserved, must be 0. - * - * RETURNS - * Success: S_OK. - * Failure: E_INVALIDARG, if any argument is invalid, or - * E_OUTOFMEMORY if memory allocation fails. - */ -HRESULT WINAPI RegisterBindStatusCallback( - IBindCtx *pbc, - IBindStatusCallback *pbsc, - IBindStatusCallback **ppbscPrevious, - DWORD dwReserved) -{ - IBindStatusCallback *prev; - - TRACE("(%p,%p,%p,%u)\n", pbc, pbsc, ppbscPrevious, dwReserved); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&prev))) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - if (ppbscPrevious) - *ppbscPrevious = prev; - else - IBindStatusCallback_Release(prev); - } - - return IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown *)pbsc); -} - -/*********************************************************************** - * RevokeBindStatusCallback (URLMON.@) - * - * Unregister a bind status callback. - * - * pbc [I] Binding context - * pbsc [I] Callback to unregister - * - * RETURNS - * Success: S_OK. - * Failure: E_INVALIDARG, if any argument is invalid, or - * E_FAIL if pbsc wasn't registered with pbc. - */ -HRESULT WINAPI RevokeBindStatusCallback( - IBindCtx *pbc, - IBindStatusCallback *pbsc) -{ - IBindStatusCallback *callback; - HRESULT hr = E_FAIL; - - TRACE("(%p,%p)\n", pbc, pbsc); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&callback))) - { - if (callback == pbsc) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - hr = S_OK; - } - IBindStatusCallback_Release(pbsc); - } - - return hr; -} - -/*********************************************************************** * URLDownloadToFileA (URLMON.@) * * Downloads URL szURL to rile szFileName and call lpfnCB callback to diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 137ace9bfaa..59d93ab3123 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -486,35 +486,6 @@ BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext) /************************************************************************** - * SetClipboardData (USER.141) - */ -HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData) -{ - CLIPBOARDINFO cbinfo; - HANDLE16 hResult = 0; - - TRACE("(%04X, %04x) !\n", wFormat, hData); - - /* If it's not owned, data can only be set if the format doesn't exists - and its rendering is not delayed */ - if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || - (!(cbinfo.flags & CB_OWNER) && !hData)) - { - WARN("Clipboard not owned by calling task. Operation failed.\n"); - return 0; - } - - if (USER_Driver->pSetClipboardData(wFormat, hData, 0, cbinfo.flags & CB_OWNER)) - { - hResult = hData; - bCBHasChanged = TRUE; - } - - return hResult; -} - - -/************************************************************************** * SetClipboardData (USER32.@) */ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData) @@ -586,28 +557,6 @@ BOOL WINAPI IsClipboardFormatAvailable(UINT wFormat) /************************************************************************** - * GetClipboardData (USER.142) - */ -HANDLE16 WINAPI GetClipboardData16(UINT16 wFormat) -{ - HANDLE16 hData = 0; - CLIPBOARDINFO cbinfo; - - if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || - (~cbinfo.flags & CB_OPEN)) - { - WARN("Clipboard not opened by calling task.\n"); - SetLastError(ERROR_CLIPBOARD_NOT_OPEN); - return 0; - } - - if (!USER_Driver->pGetClipboardData(wFormat, &hData, NULL)) hData = 0; - - return hData; -} - - -/************************************************************************** * GetClipboardData (USER32.@) */ HANDLE WINAPI GetClipboardData(UINT wFormat) diff --git a/dlls/user32/desktop.c b/dlls/user32/desktop.c index 4fbb2d969fa..37774b8b243 100644 --- a/dlls/user32/desktop.c +++ b/dlls/user32/desktop.c @@ -179,24 +179,6 @@ BOOL WINAPI PaintDesktop(HDC hdc) } /*********************************************************************** - * OldSetDeskPattern (USER.279) - */ -BOOL16 WINAPI SetDeskPattern(void) -{ - return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE ); -} - - -/*********************************************************************** - * SetDeskWallPaper (USER.285) - */ -BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename ) -{ - return SetDeskWallPaper( filename ); -} - - -/*********************************************************************** * SetDeskWallPaper (USER32.@) * * FIXME: is there a unicode version? diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index e2bf43baf4c..fad5a4831ff 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -1417,7 +1417,8 @@ static LRESULT LISTBOX_SelectItemRange( LB_DESCR *descr, INT first, static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index, BOOL on, BOOL send_notify ) { - TRACE( "index=%d notify=%s\n", index, send_notify ? "YES" : "NO" ); + TRACE( "cur_sel=%d index=%d notify=%s\n", + descr->selected_item, index, send_notify ? "YES" : "NO" ); if (descr->style & LBS_NOSEL) { @@ -2899,7 +2900,7 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg, /* fall through */ case LB_SETCURSEL: if (IS_MULTISELECT(descr)) return LB_ERR; - LISTBOX_SetCaretIndex( descr, wParam, TRUE ); + LISTBOX_SetCaretIndex( descr, wParam, FALSE ); ret = LISTBOX_SetSelection( descr, wParam, TRUE, FALSE ); if (lphc && ret != LB_ERR) ret = descr->selected_item; return ret; diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index 7f54e2f444b..a988083cf58 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -636,7 +636,7 @@ static void test_defwndproc(void) ok(IsWindowUnicode(hwnd), "Windows should have remained Unicode\n"); ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Invalid ANSI winproc\n"); ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Invalid Unicode winproc\n"); - SetWindowLongPtrA(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc); + SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)ClassTest_WndProc); ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have switched window to ANSI\n"); DestroyWindow(hwnd); @@ -654,9 +654,9 @@ static void test_defwndproc(void) hwnd = CreateWindowExW(0, classW, NULL, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0); ok(IsWindowUnicode(hwnd) == FALSE, "Window should be ANSI\n"); - SetWindowLongPtrW(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc); + SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ClassTest_WndProc); ok(IsWindowUnicode(hwnd), "SetWindowLongPtrW should have changed window to Unicode\n"); - SetWindowLongPtrA(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc); + SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)ClassTest_WndProc); ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n"); DestroyWindow(hwnd); diff --git a/dlls/user32/tests/dde.c b/dlls/user32/tests/dde.c index 811fa286d4f..b5e05c4fb99 100644 --- a/dlls/user32/tests/dde.c +++ b/dlls/user32/tests/dde.c @@ -95,7 +95,7 @@ static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPA cmd = GlobalLock((HGLOBAL)hi); - if (!cmd || (lstrcmpW((LPCWSTR)cmd, exec_cmdW) && lstrcmpA(cmd, exec_cmdA))) + if (!cmd || (lstrcmpA(cmd, exec_cmdA) && lstrcmpW((LPCWSTR)cmd, exec_cmdW))) { trace("ignoring unknown WM_DDE_EXECUTE command\n"); /* We have to send a negative acknowledge even if we don't diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 0d47262f030..527f4c29b69 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -51,6 +51,23 @@ #define WND_POPUP_ID 2 #define WND_CHILD_ID 3 +/* encoded DRAWITEMSTRUCT into an LPARAM */ +typedef struct +{ + union + { + struct + { + UINT type : 4; /* ODT_* flags */ + UINT ctl_id : 4; /* Control ID */ + UINT item_id : 4; /* Menu item ID */ + UINT action : 4; /* ODA_* flags */ + UINT state : 16; /* ODS_* flags */ + } item; + LPARAM lp; + }; +} DRAW_ITEM_STRUCT; + static BOOL test_DestroyWindow_flag; static HWINEVENTHOOK hEvent_hook; @@ -6235,6 +6252,7 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam message == WM_PARENTNOTIFY || message == WM_CANCELMODE || message == WM_SETFOCUS || message == WM_KILLFOCUS || message == WM_ENABLE || message == WM_ENTERIDLE || + message == WM_DRAWITEM || message == WM_IME_SETCONTEXT) { switch (message) @@ -6275,6 +6293,25 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam wParam &= ~(SWP_NOZORDER); break; } + + case WM_DRAWITEM: + { + /* encode DRAWITEMSTRUCT into an LPARAM */ + DRAW_ITEM_STRUCT di; + DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; + + trace("WM_DRAWITEM: type %x, ctl_id %x, item_id %x, action %x, state %x\n", + dis->CtlType, dis->CtlID, dis->itemID, dis->itemAction, dis->itemState); + + di.item.type = dis->CtlType; + di.item.ctl_id = dis->CtlID; + di.item.item_id = dis->itemID; + di.item.action = dis->itemAction; + di.item.state = dis->itemState; + + lParam = di.lp; + break; + } } msg.message = message; @@ -6604,6 +6641,7 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam) !lstrcmpiA(buf, "my_button_class") || !lstrcmpiA(buf, "my_edit_class") || !lstrcmpiA(buf, "static") || + !lstrcmpiA(buf, "ListBox") || !lstrcmpiA(buf, "MyDialogClass") || !lstrcmpiA(buf, "#32770")) { @@ -6651,6 +6689,7 @@ static void CALLBACK win_event_proc(HWINEVENTHOOK hevent, !lstrcmpiA(buf, "my_button_class") || !lstrcmpiA(buf, "my_edit_class") || !lstrcmpiA(buf, "static") || + !lstrcmpiA(buf, "ListBox") || !lstrcmpiA(buf, "MyDialogClass") || !lstrcmpiA(buf, "#32770")) { @@ -9702,6 +9741,113 @@ static void test_dbcs_wm_char(void) DestroyWindow(hwnd); } +#define ID_LISTBOX 0x000f + +static const struct message wm_lb_setcursel_0[] = +{ + { LB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { WM_CTLCOLORLISTBOX, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00120f2 }, + { 0 } +}; +static const struct message wm_lb_setcursel_1[] = +{ + { LB_SETCURSEL, sent|wparam|lparam, 1, 0 }, + { WM_CTLCOLORLISTBOX, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00020f2 }, + { WM_CTLCOLORLISTBOX, sent|parent }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x00121f2 }, + { 0 } +}; + +#define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__) + +static LRESULT (WINAPI *listbox_orig_proc)(HWND, UINT, WPARAM, LPARAM); + +static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) +{ + struct message msg; + + /* do not log painting messages */ + if (message != WM_PAINT && + message != WM_NCPAINT && + message != WM_SYNCPAINT && + message != WM_ERASEBKGND && + message != WM_NCHITTEST && + message != WM_GETTEXT && + message != WM_GETICON && + message != WM_DEVICECHANGE) + { + trace("listbox: %p, %04x, %08lx, %08lx\n", hwnd, message, wp, lp); + + msg.message = message; + msg.flags = sent|wparam|lparam; + msg.wParam = wp; + msg.lParam = lp; + add_message(&msg); + } + + return CallWindowProcA(listbox_orig_proc, hwnd, message, wp, lp); +} + +static void check_lb_state_dbg(HWND listbox, int count, int cur_sel, + int caret_index, int top_index, int line) +{ + LRESULT ret; + + ret = SendMessage(listbox, LB_GETCOUNT, 0, 0); + ok_(__FILE__, line)(ret == count, "expected count %d, got %ld\n", count, ret); + ret = SendMessage(listbox, LB_GETCURSEL, 0, 0); + ok_(__FILE__, line)(ret == cur_sel, "expected cur sel %d, got %ld\n", cur_sel, ret); + ret = SendMessage(listbox, LB_GETCARETINDEX, 0, 0); + ok_(__FILE__, line)(ret == caret_index, "expected caret index %d, got %ld\n", caret_index, ret); + ret = SendMessage(listbox, LB_GETTOPINDEX, 0, 0); + ok_(__FILE__, line)(ret == top_index, "expected top index %d, got %ld\n", top_index, ret); +} + +static void test_listbox(void) +{ + HWND parent, listbox; + LRESULT ret; + + parent = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL, + WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | WS_VISIBLE, + 10, 10, 80, 20, parent, (HMENU)ID_LISTBOX, 0, NULL); + listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc); + + check_lb_state(listbox, 0, LB_ERR, 0, 0); + + ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1"); + ok(ret == 0, "expected 0, got %ld\n", ret); + ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2"); + ok(ret == 1, "expected 1, got %ld\n", ret); + ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 3"); + ok(ret == 2, "expected 2, got %ld\n", ret); + + check_lb_state(listbox, 3, LB_ERR, 0, 0); + + flush_sequence(); + + log_all_parent_messages++; + + trace("selecting item 0\n"); + SendMessage(listbox, LB_SETCURSEL, 0, 0); + ok_sequence(wm_lb_setcursel_0, "LB_SETCURSEL 0", FALSE ); + check_lb_state(listbox, 3, 0, 0, 0); + flush_sequence(); + + trace("selecting item 1\n"); + SendMessage(listbox, LB_SETCURSEL, 1, 0); + ok_sequence(wm_lb_setcursel_1, "LB_SETCURSEL 1", FALSE ); + check_lb_state(listbox, 3, 1, 1, 0); + + log_all_parent_messages--; + + DestroyWindow(parent); +} + START_TEST(msg) { BOOL ret; @@ -9779,6 +9925,7 @@ START_TEST(msg) test_nullCallback(); test_SetForegroundWindow(); test_dbcs_wm_char(); + test_listbox(); UnhookWindowsHookEx(hCBT_hook); if (pUnhookWinEvent) diff --git a/dlls/user32/user.exe.spec b/dlls/user32/user.exe.spec index b1dbe92ff9f..9a22d87cf60 100644 --- a/dlls/user32/user.exe.spec +++ b/dlls/user32/user.exe.spec @@ -276,7 +276,7 @@ 276 stub LockMyTask 277 pascal -ret16 GetDlgCtrlID(word) GetDlgCtrlID16 278 pascal -ret16 GetDesktopHwnd() GetDesktopHwnd16 -279 pascal -ret16 OldSetDeskPattern() SetDeskPattern +279 pascal -ret16 OldSetDeskPattern() SetDeskPattern16 280 pascal -ret16 SetSystemMenu(word word) SetSystemMenu16 281 pascal -ret16 GetSysColorBrush(word) GetSysColorBrush16 282 pascal -ret16 SelectPalette(word word word) SelectPalette16 diff --git a/dlls/user32/user16.c b/dlls/user32/user16.c index 1566f2cd24c..b8951f290e7 100644 --- a/dlls/user32/user16.c +++ b/dlls/user32/user16.c @@ -447,6 +447,24 @@ BOOL16 WINAPI EmptyClipboard16(void) /************************************************************************** + * SetClipboardData (USER.141) + */ +HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData) +{ + return HANDLE_16(SetClipboardData(wFormat, HANDLE_32(hData))); +} + + +/************************************************************************** + * GetClipboardData (USER.142) + */ +HANDLE16 WINAPI GetClipboardData16(UINT16 wFormat) +{ + return HANDLE_16(GetClipboardData(wFormat)); +} + + +/************************************************************************** * CountClipboardFormats (USER.143) */ INT16 WINAPI CountClipboardFormats16(void) @@ -909,6 +927,15 @@ void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer ) /*********************************************************************** + * OldSetDeskPattern (USER.279) + */ +BOOL16 WINAPI SetDeskPattern16(void) +{ + return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE ); +} + + +/*********************************************************************** * GetSysColorBrush (USER.281) */ HBRUSH16 WINAPI GetSysColorBrush16( INT16 index ) @@ -983,6 +1010,15 @@ WORD WINAPI GetFreeSystemResources16( WORD resType ) /*********************************************************************** + * SetDeskWallPaper (USER.285) + */ +BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename ) +{ + return SetDeskWallPaper( filename ); +} + + +/*********************************************************************** * GetClipCursor (USER.309) */ void WINAPI GetClipCursor16( RECT16 *rect ) diff --git a/dlls/uuid/uuid.c b/dlls/uuid/uuid.c index d4943ef38e6..b70f78a82d4 100644 --- a/dlls/uuid/uuid.c +++ b/dlls/uuid/uuid.c @@ -80,6 +80,7 @@ DEFINE_GUID(IID_IDirectPlaySP, 0x0c9f6360,0xcc61,0x11cf,0xac,0xec,0x0 DEFINE_GUID(IID_ISFHelper, 0x1fe68efb,0x1874,0x9812,0x56,0xdc,0x00,0x00,0x00,0x00,0x00,0x00); DEFINE_GUID(IID_IDPLobbySP, 0x5a4e5a20,0x2ced,0x11d0,0xa8,0x89,0x00,0xa0,0xc9,0x05,0x43,0x3c); DEFINE_GUID(IID_IProxyManager, 0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +DEFINE_GUID(IID_IBindStatusCallbackHolder,0x79eac9cc,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b); DEFINE_GUID(FMTID_SummaryInformation,0xF29F85E0,0x4FF9,0x1068,0xAB,0x91,0x08,0x00,0x2B,0x27,0xB3,0xD9); DEFINE_GUID(FMTID_DocSummaryInformation,0xD5CDD502,0x2E9C,0x101B,0x93,0x97,0x08,0x00,0x2B,0x2C,0xF9,0xAE); diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 65338109990..67888b26709 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -418,6 +418,9 @@ HRESULT shader_get_registers_used( else if (WINED3DSPR_RASTOUT == regtype && reg == 1) reg_maps->fog = 1; + + else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader) + reg_maps->vpos = 1; } } } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b0ca134549a..90062b8b000 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -469,6 +469,20 @@ void shader_glsl_load_constants( checkGLcall("glGetUniformLocationARB"); GL_EXTCALL(glUniform4fvARB(pos, 1, mul_low)); } + if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) { + float correction_params[4]; + pos = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection")); + checkGLcall("glGetUniformLocationARB"); + if(deviceImpl->render_offscreen) { + correction_params[0] = 0.0; + correction_params[1] = 1.0; + } else { + /* position is window relative, not viewport relative */ + correction_params[0] = ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height; + correction_params[1] = -1.0; + } + GL_EXTCALL(glUniform4fvARB(pos, 1, correction_params)); + } } } @@ -528,6 +542,7 @@ void shader_generate_glsl_declarations( shader_addline(buffer, "uniform vec4 srgb_mul_low;\n"); shader_addline(buffer, "uniform vec4 srgb_comparison;\n"); ps_impl->srgb_mode_hardcoded = 0; + extra_constants_needed++; } else { ps_impl->srgb_mode_hardcoded = 1; shader_addline(buffer, "const vec4 srgb_mul_low = {%f, %f, %f, %f};\n", @@ -544,6 +559,22 @@ void shader_generate_glsl_declarations( ps_impl->srgb_enabled = 0; ps_impl->srgb_mode_hardcoded = 1; } + if(reg_maps->vpos) { + if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) { + shader_addline(buffer, "uniform vec4 ycorrection;\n"); + ((IWineD3DPixelShaderImpl *) This)->vpos_uniform = 1; + extra_constants_needed++; + } else { + /* This happens because we do not have proper tracking of the constant registers that are + * actually used, only the max limit of the shader version + */ + FIXME("Cannot find a free uniform for vpos correction params\n"); + shader_addline(buffer, "const vec4 ycorrection = {%f, %f, 0.0, 0.0};\n", + device->render_offscreen ? 0.0 : ((IWineD3DSurfaceImpl *) device->render_targets[0])->currentDesc.Height, + device->render_offscreen ? 1.0 : -1.0); + } + shader_addline(buffer, "vec4 vpos;\n"); + } } /* Declare texture samplers */ @@ -621,6 +652,9 @@ void shader_generate_glsl_declarations( /* Start the main program */ shader_addline(buffer, "void main() {\n"); + if(pshader && reg_maps->vpos) { + shader_addline(buffer, "vpos = vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1) - 0.5;\n"); + } } /***************************************************************************** @@ -836,7 +870,7 @@ static void shader_glsl_get_register_name( case WINED3DSPR_MISCTYPE: if (reg == 0) { /* vPos */ - sprintf(tmpStr, "gl_FragCoord"); + sprintf(tmpStr, "vpos"); } else { /* gl_FrontFacing could be used for vFace, but note that * gl_FrontFacing is a bool, while vFace is a float for @@ -1312,6 +1346,27 @@ void shader_glsl_pow(SHADER_OPCODE_ARG *arg) { } } +/* Process the WINED3DSIO_LOG instruction in GLSL (dst = log2(|src0|)) + * Src0 is a scalar. Note that D3D uses the absolute of src0, while + * GLSL uses the value as-is. */ +void shader_glsl_log(SHADER_OPCODE_ARG *arg) { + SHADER_BUFFER *buffer = arg->buffer; + glsl_src_param_t src0_param; + DWORD dst_write_mask; + size_t dst_size; + + dst_write_mask = shader_glsl_append_dst(buffer, arg); + dst_size = shader_glsl_get_write_mask_size(dst_write_mask); + + shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param); + + if (dst_size > 1) { + shader_addline(buffer, "vec%d(log2(abs(%s))));\n", dst_size, src0_param.param_str); + } else { + shader_addline(buffer, "log2(abs(%s)));\n", src0_param.param_str); + } +} + /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) { CONST SHADER_OPCODE* curOpcode = arg->opcode; @@ -1479,6 +1534,17 @@ void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src2_param; DWORD write_mask, cmp_channel = 0; unsigned int i, j; + char mask_char[6]; + BOOL temp_destination = FALSE; + + DWORD src0reg = arg->src[0] & WINED3DSP_REGNUM_MASK; + DWORD src1reg = arg->src[1] & WINED3DSP_REGNUM_MASK; + DWORD src2reg = arg->src[2] & WINED3DSP_REGNUM_MASK; + DWORD src0regtype = shader_get_regtype(arg->src[0]); + DWORD src1regtype = shader_get_regtype(arg->src[1]); + DWORD src2regtype = shader_get_regtype(arg->src[2]); + DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK; + DWORD dstregtype = shader_get_regtype(arg->dst); /* Cycle through all source0 channels */ for (i=0; i<4; i++) { @@ -1490,16 +1556,38 @@ void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) { cmp_channel = WINED3DSP_WRITEMASK_0 << j; } } - write_mask = shader_glsl_append_dst_ext(arg->buffer, arg, arg->dst & (~WINED3DSP_SWIZZLE_MASK | write_mask)); - if (!write_mask) continue; + + /* Splitting the cmp instruction up in multiple lines imposes a problem: + * The first lines may overwrite source parameters of the following lines. + * Deal with that by using a temporary destination register if needed + */ + if((src0reg == dstreg && src0regtype == dstregtype) || + (src1reg == dstreg && src1regtype == dstregtype) || + (src2reg == dstreg && src2regtype == dstregtype)) { + + write_mask = shader_glsl_get_write_mask(arg->dst & (~WINED3DSP_SWIZZLE_MASK | write_mask), mask_char); + if (!write_mask) continue; + shader_addline(arg->buffer, "tmp0%s = (", mask_char); + temp_destination = TRUE; + } else { + write_mask = shader_glsl_append_dst_ext(arg->buffer, arg, arg->dst & (~WINED3DSP_SWIZZLE_MASK | write_mask)); + if (!write_mask) continue; + } shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], cmp_channel, &src0_param); shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param); shader_glsl_add_src_param(arg, arg->src[2], arg->src_addr[2], write_mask, &src2_param); - shader_addline(arg->buffer, "%s >= 0.0 ? %s : %s);\n", - src0_param.param_str, src1_param.param_str, src2_param.param_str); + shader_addline(arg->buffer, "%s >= 0.0 ? %s : %s);\n", + src0_param.param_str, src1_param.param_str, src2_param.param_str); + } + + if(temp_destination) { + shader_glsl_get_write_mask(arg->dst, mask_char); + shader_glsl_append_dst_ext(arg->buffer, arg, arg->dst); + shader_addline(arg->buffer, "tmp0%s);\n", mask_char); } + } /** Process the CND opcode in GLSL (dst = (src0 > 0.5) ? src1 : src2) */ diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 7b9a2c42ed9..8b2977bec4d 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -167,7 +167,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {WINED3DSIO_SGE, "sge", "SGE", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0}, {WINED3DSIO_ABS, "abs", "ABS", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_EXP, "exp", "EX2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, + {WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_log, 0, 0}, {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_hw_map2gl, shader_glsl_expp, 0, 0}, {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, {WINED3DSIO_DST, "dst", "DST", 1, 3, pshader_hw_map2gl, shader_glsl_dst, 0, 0}, @@ -592,6 +592,13 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader WARN("Recompiling shader because srgb correction is different and hardcoded\n"); goto recompile; } + if(This->baseShader.reg_maps.vpos && !This->vpos_uniform) { + if(This->render_offscreen != deviceImpl->render_offscreen || + This->height != ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height) { + WARN("Recompiling shader because vpos is used, hard compiled and changed\n"); + goto recompile; + } + } return WINED3D_OK; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9457615ed62..da4a90c2608 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1652,7 +1652,7 @@ typedef struct shader_reg_maps { * Use 0 as default (bit 31 is always 1 on a valid token) */ DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; char bumpmat, luminanceparams; - char usesnrm; + char usesnrm, vpos; /* Whether or not a loop is used in this shader */ char loop; @@ -1839,6 +1839,7 @@ extern void shader_glsl_call(SHADER_OPCODE_ARG* arg); extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg); extern void shader_glsl_label(SHADER_OPCODE_ARG* arg); extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg); +extern void shader_glsl_log(SHADER_OPCODE_ARG* arg); extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg); /** GLSL Pixel Shader Prototypes */ @@ -2083,6 +2084,9 @@ typedef struct IWineD3DPixelShaderImpl { char srgb_mode_hardcoded; UINT srgb_low_const; UINT srgb_cmp_const; + char vpos_uniform; + BOOL render_offscreen; + UINT height; #if 0 /* needs reworking */ PSHADERINPUTDATA input; diff --git a/dlls/winenas.drv/audio.c b/dlls/winenas.drv/audio.c index ad2bfe7dc5b..f37ed6138ab 100644 --- a/dlls/winenas.drv/audio.c +++ b/dlls/winenas.drv/audio.c @@ -56,6 +56,7 @@ #define INT8 X_INT8 #define INT16 X_INT16 #define INT32 X_INT32 +#define INT64 X_INT64 #define BOOL X_BOOL #define BYTE X_BYTE #ifdef HAVE_AUDIO_AUDIOLIB_H @@ -67,6 +68,8 @@ #undef INT8 #undef INT16 #undef INT32 +#undef INT64 +#undef LONG64 #undef BOOL #undef BYTE diff --git a/dlls/winex11.drv/bitmap.c b/dlls/winex11.drv/bitmap.c index 053c95910f5..6d4180b9fbb 100644 --- a/dlls/winex11.drv/bitmap.c +++ b/dlls/winex11.drv/bitmap.c @@ -431,7 +431,8 @@ BOOL X11DRV_DeleteBitmap( HBITMAP hbitmap ) if (GetObjectW( hbitmap, sizeof(dib), &dib ) == sizeof(dib)) X11DRV_DIB_DeleteDIBSection( physBitmap, &dib ); - if (physBitmap->glxpixmap) destroy_glxpixmap(physBitmap->glxpixmap); + if (physBitmap->glxpixmap) + destroy_glxpixmap( gdi_display, physBitmap->glxpixmap ); wine_tsx11_lock(); if (physBitmap->pixmap) XFreePixmap( gdi_display, physBitmap->pixmap ); XDeleteContext( gdi_display, (XID)hbitmap, bitmap_context ); diff --git a/dlls/winex11.drv/dce.c b/dlls/winex11.drv/dce.c index aa37a4af418..11d869e8c34 100644 --- a/dlls/winex11.drv/dce.c +++ b/dlls/winex11.drv/dce.c @@ -151,11 +151,15 @@ static void update_visible_region( struct dce *dce ) { escape.drawable = data->icon_window; escape.fbconfig_id = 0; + escape.gl_drawable = 0; + escape.pixmap = 0; } else { escape.drawable = X11DRV_get_whole_window( top ); escape.fbconfig_id = X11DRV_get_fbconfig_id( dce->hwnd ); + escape.gl_drawable = X11DRV_get_gl_drawable( dce->hwnd ); + escape.pixmap = X11DRV_get_gl_pixmap( dce->hwnd ); } escape.code = X11DRV_SET_DRAWABLE; @@ -192,6 +196,8 @@ static void release_dce( struct dce *dce ) SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left, virtual_screen_rect.bottom - virtual_screen_rect.top ); escape.fbconfig_id = 0; + escape.gl_drawable = 0; + escape.pixmap = 0; ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); } diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 9000d0a1e60..634a95a66df 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -341,6 +341,8 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID physDev->drawable = data->drawable; physDev->drawable_rect = data->drawable_rect; physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id ); + physDev->gl_drawable = data->gl_drawable; + physDev->pixmap = data->pixmap; wine_tsx11_lock(); XSetSubwindowMode( gdi_display, physDev->gc, data->mode ); wine_tsx11_unlock(); diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index e3d32859629..8224f68de2e 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -111,9 +111,8 @@ typedef struct wine_glcontext { BOOL do_escape; X11DRV_PDEVICE *physDev; X11DRV_PDEVICE *pReadDev; - RECT viewport; - RECT scissor; - BOOL scissor_enabled; + Drawable drawables[2]; + BOOL refresh_drawables; struct wine_glcontext *next; struct wine_glcontext *prev; } Wine_GLContext; @@ -257,26 +256,24 @@ static BOOL (*pglXDrawableAttribATI)(Display *dpy, GLXDrawable draw, const int static void* (*pglXAllocateMemoryNV)(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); static void (*pglXFreeMemoryNV)(GLvoid *pointer); +/* MESA GLX Extensions */ +static void (*pglXCopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); + /* Standard OpenGL */ MAKE_FUNCPTR(glBindTexture) MAKE_FUNCPTR(glBitmap) MAKE_FUNCPTR(glCopyTexSubImage1D) MAKE_FUNCPTR(glCopyTexImage2D) MAKE_FUNCPTR(glCopyTexSubImage2D) -MAKE_FUNCPTR(glDisable) MAKE_FUNCPTR(glDrawBuffer) -MAKE_FUNCPTR(glEnable) MAKE_FUNCPTR(glEndList) MAKE_FUNCPTR(glGetError) MAKE_FUNCPTR(glGetIntegerv) MAKE_FUNCPTR(glGetString) -MAKE_FUNCPTR(glIsEnabled) MAKE_FUNCPTR(glNewList) MAKE_FUNCPTR(glPixelStorei) MAKE_FUNCPTR(glReadPixels) -MAKE_FUNCPTR(glScissor) MAKE_FUNCPTR(glTexImage2D) -MAKE_FUNCPTR(glViewport) MAKE_FUNCPTR(glFinish) MAKE_FUNCPTR(glFlush) #undef MAKE_FUNCPTR @@ -416,20 +413,15 @@ LOAD_FUNCPTR(glBitmap) LOAD_FUNCPTR(glCopyTexSubImage1D) LOAD_FUNCPTR(glCopyTexImage2D) LOAD_FUNCPTR(glCopyTexSubImage2D) -LOAD_FUNCPTR(glDisable) LOAD_FUNCPTR(glDrawBuffer) -LOAD_FUNCPTR(glEnable) LOAD_FUNCPTR(glEndList) LOAD_FUNCPTR(glGetError) LOAD_FUNCPTR(glGetIntegerv) LOAD_FUNCPTR(glGetString) -LOAD_FUNCPTR(glIsEnabled) LOAD_FUNCPTR(glNewList) LOAD_FUNCPTR(glPixelStorei) LOAD_FUNCPTR(glReadPixels) -LOAD_FUNCPTR(glScissor) LOAD_FUNCPTR(glTexImage2D) -LOAD_FUNCPTR(glViewport) LOAD_FUNCPTR(glFinish) LOAD_FUNCPTR(glFlush) #undef LOAD_FUNCPTR @@ -519,6 +511,10 @@ LOAD_FUNCPTR(glXFreeMemoryNV) pglXDrawableAttribATI = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribATI"); } + if(glxRequireExtension("GLX_MESA_copy_sub_buffer")) { + pglXCopySubBufferMESA = (void*)pglXGetProcAddressARB((const GLubyte *) "glXCopySubBufferMESA"); + } + X11DRV_WineGL_LoadExtensions(); wine_tsx11_unlock(); @@ -953,6 +949,42 @@ int pixelformat_from_fbconfig_id(XID fbconfig_id) } +/* Mark any allocated context using the glx drawable 'old' to use 'new' */ +void mark_drawable_dirty(Drawable old, Drawable new) +{ + Wine_GLContext *ctx; + for (ctx = context_list; ctx; ctx = ctx->next) { + if (old == ctx->drawables[0]) { + ctx->drawables[0] = new; + ctx->refresh_drawables = TRUE; + } + if (old == ctx->drawables[1]) { + ctx->drawables[1] = new; + ctx->refresh_drawables = TRUE; + } + } +} + +/* Given the current context, make sure its drawable is sync'd */ +static inline void sync_context(Wine_GLContext *context) +{ + if(context && context->refresh_drawables) { + if (glxRequireVersion(3)) + pglXMakeContextCurrent(gdi_display, context->drawables[0], + context->drawables[1], context->ctx); + else + pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx); + context->refresh_drawables = FALSE; + } +} + + +Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent) +{ + return pglXCreateGLXPixmap(display, vis, parent); +} + + /** * X11DRV_ChoosePixelFormat * @@ -1406,6 +1438,8 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev, ERR("Couldn't set format of the window, returning failure\n"); return FALSE; } + + physDev->gl_drawable = X11DRV_get_gl_drawable(hwnd); } physDev->current_pf = iPixelFormat; @@ -1568,53 +1602,6 @@ PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc) return NULL; } -/*********************************************************************** - * sync_current_drawable - * - * Adjust the current viewport and scissor in order to position - * and size the current drawable correctly on the parent window. - */ -static void sync_current_drawable(BOOL updatedc) -{ - int dy; - int width; - int height; - RECT rc; - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; - - TRACE("\n"); - - if (ctx && ctx->physDev) - { - if (updatedc) - GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */ - - dy = ctx->physDev->drawable_rect.bottom - ctx->physDev->drawable_rect.top - - ctx->physDev->dc_rect.bottom; - width = ctx->physDev->dc_rect.right - ctx->physDev->dc_rect.left; - height = ctx->physDev->dc_rect.bottom - ctx->physDev->dc_rect.top; - - wine_tsx11_lock(); - - pglViewport(ctx->physDev->dc_rect.left + ctx->viewport.left, - dy + ctx->viewport.top, - ctx->viewport.right ? (ctx->viewport.right - ctx->viewport.left) : width, - ctx->viewport.bottom ? (ctx->viewport.bottom - ctx->viewport.top) : height); - - pglEnable(GL_SCISSOR_TEST); - - if (ctx->scissor_enabled) - pglScissor(ctx->physDev->dc_rect.left + min(width, max(0, ctx->scissor.left)), - dy + min(height, max(0, ctx->scissor.top)), - min(width, max(0, ctx->scissor.right - ctx->scissor.left)), - min(height, max(0, ctx->scissor.bottom - ctx->scissor.top))); - else - pglScissor(ctx->physDev->dc_rect.left, dy, width, height); - - wine_tsx11_unlock(); - } -} - /** * X11DRV_wglMakeCurrent * @@ -1665,16 +1652,15 @@ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) { ctx->hdc = hdc; ctx->physDev = physDev; ctx->pReadDev = physDev; + ctx->drawables[0] = drawable; + ctx->drawables[1] = drawable; + ctx->refresh_drawables = FALSE; if (type == OBJ_MEMDC) { ctx->do_escape = TRUE; pglDrawBuffer(GL_FRONT_LEFT); } - else - { - sync_current_drawable(FALSE); - } } } wine_tsx11_unlock(); @@ -1718,6 +1704,9 @@ BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* p ctx->hdc = pDrawDev->hdc; ctx->physDev = pDrawDev; ctx->pReadDev = pReadDev; + ctx->drawables[0] = d_draw; + ctx->drawables[1] = d_read; + ctx->refresh_drawables = FALSE; ret = pglXMakeContextCurrent(gdi_display, d_draw, d_read, ctx->ctx); NtCurrentTeb()->glContext = ctx; } @@ -1941,40 +1930,6 @@ BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count return TRUE; } -static void WINAPI X11DRV_wglDisable(GLenum cap) -{ - if (cap == GL_SCISSOR_TEST) - { - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; - - if (ctx) - ctx->scissor_enabled = FALSE; - } - else - { - wine_tsx11_lock(); - pglDisable(cap); - wine_tsx11_unlock(); - } -} - -static void WINAPI X11DRV_wglEnable(GLenum cap) -{ - if (cap == GL_SCISSOR_TEST) - { - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; - - if (ctx) - ctx->scissor_enabled = TRUE; - } - else - { - wine_tsx11_lock(); - pglEnable(cap); - wine_tsx11_unlock(); - } -} - /* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params) { @@ -2012,67 +1967,48 @@ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params) wine_tsx11_unlock(); } -static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap) +static inline void update_drawable(X11DRV_PDEVICE *physDev) { - GLboolean enabled = False; - - if (cap == GL_SCISSOR_TEST) - { - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + int w, h; - if (ctx) - enabled = ctx->scissor_enabled; - } - else - { - wine_tsx11_lock(); - enabled = pglIsEnabled(cap); - wine_tsx11_unlock(); - } - return enabled; -} + if(!physDev->gl_drawable) + return; -static void WINAPI X11DRV_wglScissor(GLint x, GLint y, GLsizei width, GLsizei height) -{ - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + w = physDev->dc_rect.right - physDev->dc_rect.left; + h = physDev->dc_rect.bottom - physDev->dc_rect.top; - if (ctx) - { - ctx->scissor.left = x; - ctx->scissor.top = y; - ctx->scissor.right = x + width; - ctx->scissor.bottom = y + height; + if(w > 0 && h > 0) { + Drawable src = physDev->pixmap; + if(!src) src = physDev->gl_drawable; - sync_current_drawable(TRUE); + /* The GL drawable may be lagged behind if we don't flush first, so + * flush the display make sure we copy up-to-date data */ + XFlush(gdi_display); + XCopyArea(gdi_display, src, physDev->drawable, physDev->gc, 0, 0, w, h, + physDev->dc_rect.left, physDev->dc_rect.top); } } -static void WINAPI X11DRV_wglViewport(GLint x, GLint y, GLsizei width, GLsizei height) -{ - Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; - - if (ctx) - { - ctx->viewport.left = x; - ctx->viewport.top = y; - ctx->viewport.right = x + width; - ctx->viewport.bottom = y + height; - - sync_current_drawable(TRUE); - } -} static void WINAPI X11DRV_wglFinish(void) { + Wine_GLContext *ctx = NtCurrentTeb()->glContext; + wine_tsx11_lock(); + sync_context(ctx); pglFinish(); + update_drawable(ctx->physDev); wine_tsx11_unlock(); } static void WINAPI X11DRV_wglFlush(void) { + Wine_GLContext *ctx = NtCurrentTeb()->glContext; + wine_tsx11_lock(); + sync_context(ctx); pglFlush(); + update_drawable(ctx->physDev); wine_tsx11_unlock(); } @@ -3109,12 +3045,7 @@ static const WineGLExtension WGL_internal_functions = { "", { - { "wglDisable", X11DRV_wglDisable }, - { "wglEnable", X11DRV_wglEnable }, { "wglGetIntegerv", X11DRV_wglGetIntegerv }, - { "wglIsEnabled", X11DRV_wglIsEnabled }, - { "wglScissor", X11DRV_wglScissor }, - { "wglViewport", X11DRV_wglViewport }, { "wglFinish", X11DRV_wglFinish }, { "wglFlush", X11DRV_wglFlush }, } @@ -3273,7 +3204,7 @@ static void X11DRV_WineGL_LoadExtensions(void) } -static XID create_glxpixmap(X11DRV_PDEVICE *physDev) +static XID create_bitmap_glxpixmap(X11DRV_PDEVICE *physDev) { GLXPixmap ret; XVisualInfo *vis; @@ -3304,19 +3235,21 @@ Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) else { if(!physDev->bitmap->glxpixmap) - physDev->bitmap->glxpixmap = create_glxpixmap(physDev); + physDev->bitmap->glxpixmap = create_bitmap_glxpixmap(physDev); ret = physDev->bitmap->glxpixmap; } } + else if(physDev->gl_drawable) + ret = physDev->gl_drawable; else ret = physDev->drawable; return ret; } -BOOL destroy_glxpixmap(XID glxpixmap) +BOOL destroy_glxpixmap(Display *display, XID glxpixmap) { wine_tsx11_lock(); - pglXDestroyGLXPixmap(gdi_display, glxpixmap); + pglXDestroyGLXPixmap(display, glxpixmap); wine_tsx11_unlock(); return TRUE; } @@ -3329,6 +3262,8 @@ BOOL destroy_glxpixmap(XID glxpixmap) BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) { GLXDrawable drawable; + Wine_GLContext *ctx = NtCurrentTeb()->glContext; + if (!has_opengl()) { ERR("No libGL on this box - disabling OpenGL support !\n"); return 0; @@ -3337,8 +3272,27 @@ BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) TRACE_(opengl)("(%p)\n", physDev); drawable = get_glxdrawable(physDev); + wine_tsx11_lock(); - pglXSwapBuffers(gdi_display, drawable); + sync_context(ctx); + if(physDev->pixmap) { + if(pglXCopySubBufferMESA) { + int w = physDev->dc_rect.right - physDev->dc_rect.left; + int h = physDev->dc_rect.bottom - physDev->dc_rect.top; + + /* (glX)SwapBuffers has an implicit glFlush effect, however + * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before + * copying */ + pglFlush(); + if(w > 0 && h > 0) + pglXCopySubBufferMESA(gdi_display, drawable, 0, 0, w, h); + } + else + pglXSwapBuffers(gdi_display, drawable); + } + else + pglXSwapBuffers(gdi_display, drawable); + update_drawable(physDev); wine_tsx11_unlock(); /* FPS support */ @@ -3400,6 +3354,16 @@ XVisualInfo *X11DRV_setup_opengl_visual( Display *display ) return visual; } +XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ) +{ + WineGLPixelFormat *fmt; + + fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fbconfig_id); + if(fmt == NULL) + return NULL; + return pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig); +} + #else /* no OpenGL includes */ int pixelformat_from_fbconfig_id(XID fbconfig_id) @@ -3407,6 +3371,15 @@ int pixelformat_from_fbconfig_id(XID fbconfig_id) return 0; } +void mark_drawable_dirty(Drawable old, Drawable new) +{ +} + +Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent) +{ + return 0; +} + /*********************************************************************** * ChoosePixelFormat (X11DRV.@) */ @@ -3551,9 +3524,14 @@ Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) return 0; } -BOOL destroy_glxpixmap(XID glxpixmap) +BOOL destroy_glxpixmap(Display *display, XID glxpixmap) { return FALSE; } +XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ) +{ + return NULL; +} + #endif /* defined(HAVE_OPENGL) */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index dcdfccb9332..f1ee388961b 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -40,6 +40,7 @@ #include "wine/unicode.h" #include "x11drv.h" +#include "xcomposite.h" #include "wine/debug.h" #include "wine/server.h" #include "win.h" @@ -56,12 +57,16 @@ static XContext win_data_context; static const char whole_window_prop[] = "__wine_x11_whole_window"; static const char icon_window_prop[] = "__wine_x11_icon_window"; static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id"; +static const char gl_drawable_prop[] = "__wine_x11_gl_drawable"; +static const char pixmap_prop[] = "__wine_x11_pixmap"; static const char managed_prop[] = "__wine_x11_managed"; static const char visual_id_prop[] = "__wine_x11_visual_id"; /* for XDG systray icons */ #define SYSTEM_TRAY_REQUEST_DOCK 0 +extern int usexcomposite; + /*********************************************************************** * is_window_managed * @@ -187,16 +192,203 @@ void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data ) */ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) { + Display *display = thread_display(); struct x11drv_win_data *data; + XVisualInfo *vis; + Drawable parent; + HWND next_hwnd; + int w, h; if (!(data = X11DRV_get_win_data(hwnd))) return FALSE; + wine_tsx11_lock(); + + vis = visual_from_fbconfig_id(fbconfig_id); + if(!vis) return FALSE; + + if(data->whole_window && vis->visualid == XVisualIDFromVisual(visual)) + { + TRACE("Whole window available and visual match, rendering onscreen\n"); + goto done; + } + + wine_tsx11_unlock(); + + parent = data->whole_window; + next_hwnd = hwnd; + while(!parent) + { + next_hwnd = GetAncestor(next_hwnd, GA_PARENT); + if(!next_hwnd) + { + ERR("Could not find parent HWND with a drawable!\n"); + return FALSE; + } + parent = X11DRV_get_whole_window(next_hwnd); + } + + w = data->client_rect.right - data->client_rect.left; + h = data->client_rect.bottom - data->client_rect.top; + + if(w <= 0) w = 1; + if(h <= 0) h = 1; + + wine_tsx11_lock(); +#ifdef SONAME_LIBXCOMPOSITE + if(usexcomposite) + { + XSetWindowAttributes attrib; + + attrib.override_redirect = True; + attrib.colormap = XCreateColormap(display, parent, vis->visual, + (vis->class == PseudoColor || + vis->class == GrayScale || + vis->class == DirectColor) ? + AllocAll : AllocNone); + XInstallColormap(gdi_display, attrib.colormap); + + data->gl_drawable = XCreateWindow(display, parent, -w, 0, w, h, 0, + vis->depth, InputOutput, vis->visual, + CWColormap | CWOverrideRedirect, + &attrib); + if(data->gl_drawable) + { + pXCompositeRedirectWindow(display, data->gl_drawable, + CompositeRedirectManual); + XMapWindow(display, data->gl_drawable); + } + } + else +#endif + { + WARN("XComposite is not available, using GLXPixmap hack\n"); + + data->pixmap = XCreatePixmap(display, parent, w, h, vis->depth); + if(!data->pixmap) + { + ERR("Failed to create pixmap for offscreen rendering\n"); + XFree(vis); + wine_tsx11_unlock(); + return FALSE; + } + + data->gl_drawable = create_glxpixmap(display, vis, data->pixmap); + if(!data->gl_drawable) + { + XFreePixmap(display, data->pixmap); + data->pixmap = 0; + } + } + + if(!data->gl_drawable) + { + ERR("Failed to create drawable for offscreen rendering\n"); + XFree(vis); + wine_tsx11_unlock(); + return FALSE; + } + +done: + XFree(vis); + + XFlush(display); + wine_tsx11_unlock(); + + TRACE("Created GL drawable 0x%lx, using FBConfigID 0x%lx\n", + data->gl_drawable, fbconfig_id); + data->fbconfig_id = fbconfig_id; SetPropA(hwnd, fbconfig_id_prop, (HANDLE)data->fbconfig_id); + SetPropA(hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable); + SetPropA(hwnd, pixmap_prop, (HANDLE)data->pixmap); invalidate_dce( hwnd, &data->window_rect ); return TRUE; } +static void update_gl_drawable(Display *display, struct x11drv_win_data *data, const RECT *old_client_rect) +{ + int w = data->client_rect.right - data->client_rect.left; + int h = data->client_rect.bottom - data->client_rect.top; + XVisualInfo *vis; + Drawable parent; + HWND next_hwnd; + Drawable glxp; + Pixmap pix; + + if((w == old_client_rect->right - old_client_rect->left && + h == old_client_rect->bottom - old_client_rect->top) || + w <= 0 || h <= 0) + { + TRACE("No resize needed\n"); + return; + } + + TRACE("Resizing GL drawable 0x%lx to %dx%d\n", data->gl_drawable, w, h); +#ifdef SONAME_LIBXCOMPOSITE + if(usexcomposite) + { + wine_tsx11_lock(); + XMoveResizeWindow(display, data->gl_drawable, -w, 0, w, h); + wine_tsx11_unlock(); + return; + } +#endif + + parent = data->whole_window; + next_hwnd = data->hwnd; + while(!parent) + { + next_hwnd = GetAncestor(next_hwnd, GA_PARENT); + if(!next_hwnd) + { + ERR("Could not find parent HWND with a drawable!\n"); + return; + } + parent = X11DRV_get_whole_window(next_hwnd); + } + + wine_tsx11_lock(); + + vis = visual_from_fbconfig_id(data->fbconfig_id); + if(!vis) return; + + pix = XCreatePixmap(display, parent, w, h, vis->depth); + if(!pix) + { + ERR("Failed to create pixmap for offscreen rendering\n"); + XFree(vis); + wine_tsx11_unlock(); + return; + } + + glxp = create_glxpixmap(display, vis, pix); + if(!glxp) + { + ERR("Failed to create drawable for offscreen rendering\n"); + XFreePixmap(display, pix); + XFree(vis); + wine_tsx11_unlock(); + return; + } + + XFree(vis); + + mark_drawable_dirty(data->gl_drawable, glxp); + + XFreePixmap(display, data->pixmap); + destroy_glxpixmap(display, data->gl_drawable); + + data->pixmap = pix; + data->gl_drawable = glxp; + + XFlush(display); + wine_tsx11_unlock(); + + SetPropA(data->hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable); + SetPropA(data->hwnd, pixmap_prop, (HANDLE)data->pixmap); + invalidate_dce( data->hwnd, &data->window_rect ); +} + /*********************************************************************** * get_window_changes @@ -741,13 +933,18 @@ void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data XWindowChanges changes; int mask; RECT old_whole_rect; + RECT old_client_rect; old_whole_rect = data->whole_rect; data->whole_rect = *new_whole_rect; + old_client_rect = data->client_rect; data->client_rect = *new_client_rect; OffsetRect( &data->client_rect, -data->whole_rect.left, -data->whole_rect.top ); + if (data->gl_drawable) + update_gl_drawable(display, data, &old_client_rect); + if (!data->whole_window || data->lock_changes) return; mask = get_window_changes( &changes, &old_whole_rect, &data->whole_rect ); @@ -946,6 +1143,20 @@ void X11DRV_DestroyWindow( HWND hwnd ) if (!(data = X11DRV_get_win_data( hwnd ))) return; + if (data->pixmap) + { + destroy_glxpixmap(display, data->gl_drawable); + wine_tsx11_lock(); + XFreePixmap(display, data->pixmap); + wine_tsx11_unlock(); + } + else if (data->gl_drawable) + { + wine_tsx11_lock(); + XDestroyWindow(display, data->gl_drawable); + wine_tsx11_unlock(); + } + free_window_dce( data ); destroy_whole_window( display, data ); destroy_icon_window( display, data ); @@ -971,6 +1182,8 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) data->whole_window = 0; data->icon_window = 0; data->fbconfig_id = 0; + data->gl_drawable = 0; + data->pixmap = 0; data->xic = 0; data->managed = FALSE; data->dce = NULL; @@ -1276,6 +1489,32 @@ XID X11DRV_get_fbconfig_id( HWND hwnd ) return data->fbconfig_id; } +/*********************************************************************** + * X11DRV_get_gl_drawable + * + * Return the GL drawable for this window. + */ +Drawable X11DRV_get_gl_drawable( HWND hwnd ) +{ + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); + + if (!data) return (Drawable)GetPropA( hwnd, gl_drawable_prop ); + return data->gl_drawable; +} + +/*********************************************************************** + * X11DRV_get_gl_pixmap + * + * Return the Pixmap associated with the GL drawable (if any) for this window. + */ +Pixmap X11DRV_get_gl_pixmap( HWND hwnd ) +{ + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); + + if (!data) return (Pixmap)GetPropA( hwnd, pixmap_prop ); + return data->pixmap; +} + /*********************************************************************** * X11DRV_get_ic diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f61dc98f2e9..05f8d1cf09a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -139,6 +139,8 @@ typedef struct int exposures; /* count of graphics exposures operations */ struct dce *dce; /* opaque pointer to DCE */ int current_pf; + Drawable gl_drawable; + Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */ XRENDERINFO xrender; } X11DRV_PDEVICE; @@ -272,7 +274,7 @@ extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev); extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display); extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev); -extern BOOL destroy_glxpixmap(XID glxpixmap); +extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap); /* XIM support */ extern XIC X11DRV_CreateIC(XIM xim, Display *display, Window win); @@ -486,6 +488,8 @@ struct x11drv_escape_set_drawable RECT dc_rect; /* DC rectangle relative to drawable */ RECT drawable_rect;/* Drawable rectangle relative to screen */ XID fbconfig_id; /* fbconfig id used by the GL drawable */ + Drawable gl_drawable; /* GL drawable */ + Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */ }; struct x11drv_escape_set_dce @@ -645,6 +649,8 @@ struct x11drv_win_data Window whole_window; /* X window for the complete window */ Window icon_window; /* X window for the icon */ XID fbconfig_id; /* fbconfig id for the GL drawable this hwnd uses */ + Drawable gl_drawable; /* Optional GL drawable for rendering the client area */ + Pixmap pixmap; /* Base pixmap for if gl_drawable is a GLXPixmap */ RECT window_rect; /* USER window rectangle relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to whole window */ @@ -660,11 +666,16 @@ struct x11drv_win_data extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd ); extern Window X11DRV_get_whole_window( HWND hwnd ); extern XID X11DRV_get_fbconfig_id( HWND hwnd ); +extern Drawable X11DRV_get_gl_drawable( HWND hwnd ); +extern Pixmap X11DRV_get_gl_pixmap( HWND hwnd ); extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect ); extern XIC X11DRV_get_ic( HWND hwnd ); extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig ); extern int pixelformat_from_fbconfig_id( XID fbconfig_id ); +extern XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ); +extern void mark_drawable_dirty( Drawable old, Drawable new ); +extern Drawable create_glxpixmap( Display *display, XVisualInfo *vis, Pixmap parent ); extern void alloc_window_dce( struct x11drv_win_data *data ); extern void free_window_dce( struct x11drv_win_data *data ); diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index c792eff4363..b768ed80a1e 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -36,13 +36,14 @@ #include "wine/unicode.h" #include "wine/debug.h" -static BOOL X11DRV_XRender_Installed = FALSE; int using_client_side_fonts = FALSE; WINE_DEFAULT_DEBUG_CHANNEL(xrender); #ifdef SONAME_LIBXRENDER +static BOOL X11DRV_XRender_Installed = FALSE; + #include #include diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index cba5b052d87..b1620b9d5e9 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3916,6 +3916,19 @@ struct set_security_object_reply struct reply_header __header; }; +struct get_security_object_request +{ + struct request_header __header; + obj_handle_t handle; + unsigned int security_info; +}; +struct get_security_object_reply +{ + struct reply_header __header; + unsigned int sd_len; + /* VARARG(sd,security_descriptor); */ +}; + struct create_mailslot_request { @@ -4465,6 +4478,7 @@ enum request REQ_get_token_user, REQ_get_token_groups, REQ_set_security_object, + REQ_get_security_object, REQ_create_mailslot, REQ_set_mailslot_info, REQ_create_directory, @@ -4703,6 +4717,7 @@ union generic_request struct get_token_user_request get_token_user_request; struct get_token_groups_request get_token_groups_request; struct set_security_object_request set_security_object_request; + struct get_security_object_request get_security_object_request; struct create_mailslot_request create_mailslot_request; struct set_mailslot_info_request set_mailslot_info_request; struct create_directory_request create_directory_request; @@ -4939,6 +4954,7 @@ union generic_reply struct get_token_user_reply get_token_user_reply; struct get_token_groups_reply get_token_groups_reply; struct set_security_object_reply set_security_object_reply; + struct get_security_object_reply get_security_object_reply; struct create_mailslot_reply create_mailslot_reply; struct set_mailslot_info_reply set_mailslot_info_reply; struct create_directory_reply create_directory_reply; @@ -4963,6 +4979,6 @@ union generic_reply struct set_completion_info_reply set_completion_info_reply; }; -#define SERVER_PROTOCOL_VERSION 315 +#define SERVER_PROTOCOL_VERSION 316 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/programs/net/Ru.rc b/programs/net/Ru.rc new file mode 100644 index 00000000000..17c2c81df53 --- /dev/null +++ b/programs/net/Ru.rc @@ -0,0 +1,40 @@ +/* + * NET.EXE - Wine-compatible net program + * Russian language support + * + * Copyright (C) 2007 Konstantin Kondratyuk (Etersoft) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_USAGE, "Èñïîëüçîâàíèå:\n\nNET [ HELP | START | STOP ]\n" + STRING_START_USAGE, "Óêàæèòå çàïóñêàåìóþ ñëóæáó.\n" + STRING_STOP_USAGE, "Óêàæèòå îñòàíàâëèâàåìóþ ñëóæáó.\n" + STRING_STOP_DEP, "Îñòàíîâêà çàâèñèìîé ñëóæáû: %s\n" + STRING_CANT_STOP, "Íåâîçìîæíî îñòàíîâèòü ñëóæáó %s\n" + STRING_NO_SCM, "Íåâîçìîæíî ïîëó÷èòü äîñòóï ê äèñïåò÷åðó ñëóæá.\n" + STRING_NO_SVCHANDLE, "Íåâîçìîæíî ïîëó÷èòü äîñòóï ê ñëóæáå.\n" + STRING_START_SVC, "Çàïóñê ñëóæáû %s.\n" + STRING_START_SVC_SUCCESS, "Ñëóæáà %s óñïåøíî çàïóùåíà.\n" + STRING_START_SVC_FAIL, "Îøèáêà ïðè çàïóñêå ñëóæáû %s.\n" + STRING_STOP_SVC, "Îñòàíîâêà ñëóæáû %s.\n" + STRING_STOP_SVC_SUCCESS, "Ñëóæáà %s óñïåøíî îñòàíîâëåíà.\n" + STRING_STOP_SVC_FAIL, "Îøèáêà ïðè îñòàíîâêå ñëóæáû %s.\n" + STRING_HELP_USAGE, "Èñïîëüçîâàíèå:\n\nNET HELP êîìàíäà\n -èëè-\nNET êîìàíäà /HELP\n\n Äîñòóïíûå êîìàíäû:\n NET HELP NET START NET STOP\n" +} diff --git a/programs/net/net.c b/programs/net/net.c index 73e176373d8..4bc365279dd 100644 --- a/programs/net/net.c +++ b/programs/net/net.c @@ -99,8 +99,8 @@ static BOOL net_service(int operation, char *service_name) output_string(STRING_START_SVC, service_display_name); result = StartService(serviceHandle, 0, NULL); - if(result) output_string(STRING_START_SVC_SUCCESS); - else output_string(STRING_START_SVC_FAIL); + if(result) output_string(STRING_START_SVC_SUCCESS, service_display_name); + else output_string(STRING_START_SVC_FAIL, service_display_name); break; case NET_STOP: output_string(STRING_STOP_SVC, service_display_name); diff --git a/programs/net/rsrc.rc b/programs/net/rsrc.rc index 31252522419..a6a1c401aa7 100644 --- a/programs/net/rsrc.rc +++ b/programs/net/rsrc.rc @@ -24,3 +24,4 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "En.rc" #include "Ko.rc" +#include "Ru.rc" diff --git a/programs/winecfg/En.rc b/programs/winecfg/En.rc index 93f5091aadd..0351ef20409 100644 --- a/programs/winecfg/En.rc +++ b/programs/winecfg/En.rc @@ -64,28 +64,28 @@ FONT 8, "MS Shell Dlg" BEGIN GROUPBOX " Window Settings ",IDC_STATIC,8,4,244,184 - CONTROL "Allow DirectX apps to stop the mouse leaving their window",IDC_DX_MOUSE_GRAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,19,230,8 + CONTROL "Allow DirectX apps to stop the &mouse leaving their window",IDC_DX_MOUSE_GRAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,19,230,8 - CONTROL "Allow the window manager to control the windows",IDC_ENABLE_MANAGED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,40,230,8 + CONTROL "Allow the &window manager to control the windows",IDC_ENABLE_MANAGED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,40,230,8 LTEXT "If windows are managed by your window manager, then they will have the standard borders, they will respect your virtual desktop and appear in your window list. \n\nIf the windows are unmanaged, they will be disconnected from your window manager. This will mean the windows do not integrate as closely with your desktop, but the emulation will be more accurate so it can help some programs to work better.", IDC_STATIC,19,51,225,80 - CONTROL "Emulate a virtual desktop",IDC_ENABLE_DESKTOP,"Button", + CONTROL "Emulate a virtual &desktop",IDC_ENABLE_DESKTOP,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,15,128,230,10 LTEXT "You can either choose to have all Windows applications confined to a single window acting as a virtual desktop, or to have them behave like your other applications.", IDC_STATIC,19,138,225,28 - LTEXT "Desktop size:",IDC_DESKTOP_SIZE,15,168,44,8,WS_DISABLED + LTEXT "Desktop &size:",IDC_DESKTOP_SIZE,15,168,44,8,WS_DISABLED LTEXT "X",IDC_DESKTOP_BY,109,168,8,8,WS_DISABLED EDITTEXT IDC_DESKTOP_WIDTH,64,166,40,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED EDITTEXT IDC_DESKTOP_HEIGHT,117,166,40,12,ES_AUTOHSCROLL | ES_NUMBER | WS_DISABLED GROUPBOX " Direct3D ",IDC_STATIC,8,190,244,48 - LTEXT "Vertex Shader Support: ",IDC_STATIC,15,203,80,32 + LTEXT "&Vertex Shader Support: ",IDC_STATIC,15,203,80,32 COMBOBOX IDC_D3D_VSHADER_MODE,100,201,145,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Allow Pixel Shader (if supported by hardware)",IDC_D3D_PSHADER_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,219,230,10 - GROUPBOX " Screen Resolution ",IDC_STATIC,8,242,244,25 + CONTROL "Allow &Pixel Shader (if supported by hardware)",IDC_D3D_PSHADER_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,219,230,10 + GROUPBOX " Screen &Resolution ",IDC_STATIC,8,242,244,25 CONTROL "", IDC_RES_TRACKBAR, "msctls_trackbar32",WS_TABSTOP,12,250,187,15 EDITTEXT IDC_RES_DPIEDIT,204,250,23,13,ES_NUMBER|WS_TABSTOP LTEXT "dpi",IDC_STATIC,235,252,10,8 @@ -98,10 +98,10 @@ BEGIN GROUPBOX " DLL Overrides ",IDC_STATIC,8,4,244,240 LTEXT "Dynamic Link Libraries can be specified individually to be either builtin (provided by Wine) or native (taken from Windows or provided by the application)." ,IDC_STATIC,16,16,220,32 - LTEXT "New override for library:",IDC_STATIC,16,58,100,8 + LTEXT "&New override for library:",IDC_STATIC,16,58,100,8 COMBOBOX IDC_DLLCOMBO,16,68,140,14,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | CBS_SORT | CBS_LOWERCASE PUSHBUTTON "&Add",IDC_DLLS_ADDDLL, 164,68,82,13,BS_DEFPUSHBUTTON - LTEXT "Existing overrides:",IDC_STATIC,16,86,100,8 + LTEXT "Existing &overrides:",IDC_STATIC,16,86,100,8 LISTBOX IDC_DLLS_LIST,16,96,140,140,WS_BORDER | WS_TABSTOP | WS_VSCROLL PUSHBUTTON "&Edit",IDC_DLLS_EDITDLL,164,96,82,14 PUSHBUTTON "&Remove",IDC_DLLS_REMOVEDLL,164,114,82,14 @@ -126,7 +126,7 @@ IDD_DRIVECFG DIALOG DISCARDABLE 0, 0, 260, 250 STYLE WS_CHILD | WS_DISABLED FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX " Drive mappings ",IDC_STATIC,8,4,244,240 + GROUPBOX " Drive &mappings ",IDC_STATIC,8,4,244,240 CONTROL "Listview",IDC_LIST_DRIVES,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP, 15,18,232,76 PUSHBUTTON "&Add...",IDC_BUTTON_ADD,15,98,37,14 @@ -143,7 +143,7 @@ BEGIN LTEXT "Label and serial number",IDC_LABELSERIAL_STATIC,15,155,95,10 - PUSHBUTTON "&Show Advanced",IDC_BUTTON_SHOW_HIDE_ADVANCED,186,136,60,13 + PUSHBUTTON "Show &Advanced",IDC_BUTTON_SHOW_HIDE_ADVANCED,186,136,60,13 CONTROL "Autodetect &from Device:",IDC_RADIO_AUTODETECT,"Button", BS_AUTORADIOBUTTON,15,166,93,10 EDITTEXT IDC_EDIT_DEVICE,27,176,174,13,ES_AUTOHSCROLL @@ -156,7 +156,7 @@ BEGIN LTEXT "S&erial:",IDC_STATIC_SERIAL,33,225,29,12 EDITTEXT IDC_EDIT_SERIAL,63,221,78,13,ES_AUTOHSCROLL | WS_TABSTOP - CONTROL "Show dot files",IDC_SHOW_DOT_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,260,230,8 + CONTROL "Show &dot files",IDC_SHOW_DOT_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,260,230,8 END IDD_AUDIOCFG DIALOG DISCARDABLE 0, 0, 260, 250 @@ -166,16 +166,16 @@ BEGIN GROUPBOX " Driver Selection ",IDC_STATIC,8,4,244,195 LTEXT "Select a sound driver by checking the box of the desired driver. Disable sound by not selecting any driver. Selection of multiple drivers is not recommended. Configure a driver by right-clicking on it.",IDC_STATIC,15,20,227,30 CONTROL "Devices",IDC_AUDIO_TREE,"SysTreeView32",WS_BORDER | WS_TABSTOP,15,50,140,140 - PUSHBUTTON "Test Sound",IDC_AUDIO_TEST,170,50,59,14 - PUSHBUTTON "Control Panel",IDC_AUDIO_CONTROL_PANEL,170,70,59,14 + PUSHBUTTON "&Test Sound",IDC_AUDIO_TEST,170,50,59,14 + PUSHBUTTON "&Control Panel",IDC_AUDIO_CONTROL_PANEL,170,70,59,14 GROUPBOX " DirectSound ",IDC_STATIC,8,205,244,60 - LTEXT "Hardware Acceleration: ",IDC_STATIC,15,215,90,10 + LTEXT "&Hardware Acceleration: ",IDC_STATIC,15,215,90,10 COMBOBOX IDC_DSOUND_HW_ACCEL,100,213,150,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Default Sample Rate:",IDC_STATIC,15,232,70,8 + LTEXT "Default &Sample Rate:",IDC_STATIC,15,232,70,8 COMBOBOX IDC_DSOUND_RATES,90,230,42,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Default Bits Per Sample:",IDC_STATIC,137,232,80,8 + LTEXT "Default &Bits Per Sample:",IDC_STATIC,137,232,80,8 COMBOBOX IDC_DSOUND_BITS,220,230,30,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Driver Emulation",IDC_DSOUND_DRV_EMUL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,250,230,10 + CONTROL "Driver &Emulation",IDC_DSOUND_DRV_EMUL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,250,230,10 END IDD_DESKTOP_INTEGRATION DIALOG DISCARDABLE 0, 0, 260, 250 @@ -183,27 +183,27 @@ STYLE WS_CHILD | WS_DISABLED FONT 8, "MS Shell Dlg" BEGIN GROUPBOX " Appearance ",IDC_STATIC,8,4,244,106 - LTEXT "Theme:",IDC_STATIC,15,16,130,8 + LTEXT "&Theme:",IDC_STATIC,15,16,130,8 COMBOBOX IDC_THEME_THEMECOMBO,15,24,130,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Install theme...",IDC_THEME_INSTALL,152,23,93,14 - LTEXT "Color:",IDC_THEME_COLORTEXT,15,40,112,8 + PUSHBUTTON "&Install theme...",IDC_THEME_INSTALL,152,23,93,14 + LTEXT "&Color:",IDC_THEME_COLORTEXT,15,40,112,8 COMBOBOX IDC_THEME_COLORCOMBO,15,48,112,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Size:",IDC_THEME_SIZETEXT,135,40,110,8 + LTEXT "&Size:",IDC_THEME_SIZETEXT,135,40,110,8 COMBOBOX IDC_THEME_SIZECOMBO,135,48,110,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Item:",IDC_STATIC,15,64,112,8 + LTEXT "It&em:",IDC_STATIC,15,64,112,8 COMBOBOX IDC_SYSPARAM_COMBO,15,74,112,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | CBS_SORT - LTEXT "Color:",IDC_SYSPARAM_COLOR_TEXT,135,64,25,8,WS_DISABLED + LTEXT "C&olor:",IDC_SYSPARAM_COLOR_TEXT,135,64,25,8,WS_DISABLED PUSHBUTTON "",IDC_SYSPARAM_COLOR,135,74,25,13,WS_DISABLED | BS_OWNERDRAW - LTEXT "Size:",IDC_SYSPARAM_SIZE_TEXT,166,64,30,8,WS_DISABLED + LTEXT "Si&ze:",IDC_SYSPARAM_SIZE_TEXT,166,64,30,8,WS_DISABLED EDITTEXT IDC_SYSPARAM_SIZE,166,74,23,13,ES_AUTOHSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "",IDC_SYSPARAM_SIZE_UD,UPDOWN_CLASS,UDS_SETBUDDYINT | WS_DISABLED,187,74,15,13 - PUSHBUTTON "Font",IDC_SYSPARAM_FONT,208,74,37,13,WS_DISABLED - GROUPBOX " Shell Folder ",IDC_STATIC,8,114,244,100 + PUSHBUTTON "&Font",IDC_SYSPARAM_FONT,208,74,37,13,WS_DISABLED + GROUPBOX " S&hell Folder ",IDC_STATIC,8,114,244,100 CONTROL "Listview",IDC_LIST_SFPATHS,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP, 15,126,230,64 - CONTROL "Link to:",IDC_LINK_SFPATH,"Button",BS_AUTOCHECKBOX|WS_TABSTOP|WS_DISABLED,15,195,50,13 + CONTROL "&Link to:",IDC_LINK_SFPATH,"Button",BS_AUTOCHECKBOX|WS_TABSTOP|WS_DISABLED,15,195,50,13 EDITTEXT IDC_EDIT_SFPATH,65,195,145,13,ES_AUTOHSCROLL|WS_TABSTOP|WS_DISABLED - PUSHBUTTON "Browse",IDC_BROWSE_SFPATH,215,195,30,13,WS_DISABLED + PUSHBUTTON "B&rowse",IDC_BROWSE_SFPATH,215,195,30,13,WS_DISABLED END STRINGTABLE DISCARDABLE @@ -213,8 +213,8 @@ BEGIN IDS_TAB_DLLS "Libraries" IDS_TAB_DRIVES "Drives" IDS_CHOOSE_PATH "Select the unix target directory, please." - IDS_HIDE_ADVANCED "Hide Advanced" - IDS_SHOW_ADVANCED "Show Advanced" + IDS_HIDE_ADVANCED "Hide &Advanced" + IDS_SHOW_ADVANCED "Show &Advanced" IDS_NOTHEME "(No Theme)" IDS_TAB_GRAPHICS "Graphics" IDS_TAB_DESKTOP_INTEGRATION "Desktop Integration" diff --git a/server/change.c b/server/change.c index e996d4999e4..c8966dadf0e 100644 --- a/server/change.c +++ b/server/change.c @@ -157,7 +157,6 @@ struct dir }; static struct fd *dir_get_fd( struct object *obj ); -static unsigned int dir_map_access( struct object *obj, unsigned int access ); static void dir_dump( struct object *obj, int verbose ); static void dir_destroy( struct object *obj ); @@ -171,7 +170,7 @@ static const struct object_ops dir_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ dir_get_fd, /* get_fd */ - dir_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -289,15 +288,6 @@ static struct fd *dir_get_fd( struct object *obj ) return (struct fd *)grab_object( dir->fd ); } -static unsigned int dir_map_access( struct object *obj, unsigned int access ) -{ - if (access & GENERIC_READ) access |= FILE_GENERIC_READ; - if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; - if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; - if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; - return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); -} - static struct change_record *get_first_change_record( struct dir *dir ) { struct list *ptr = list_head( &dir->change_records ); diff --git a/server/device.c b/server/device.c index c52cd221468..e4fa5956050 100644 --- a/server/device.c +++ b/server/device.c @@ -130,7 +130,7 @@ static const struct object_ops device_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ device_get_fd, /* get_fd */ - no_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ device_open_file, /* open_file */ no_close_handle, /* close_handle */ diff --git a/server/directory.c b/server/directory.c index 55c3264cc4f..f17071102de 100644 --- a/server/directory.c +++ b/server/directory.c @@ -36,7 +36,7 @@ #include "handle.h" #include "request.h" #include "process.h" -#include "object.h" +#include "file.h" #include "unicode.h" #define HASH_SIZE 7 /* default hash size */ @@ -48,7 +48,6 @@ struct directory }; static void directory_dump( struct object *obj, int verbose ); -static unsigned int directory_map_access( struct object *obj, unsigned int access ); static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); static void directory_destroy( struct object *obj ); @@ -63,7 +62,7 @@ static const struct object_ops directory_ops = NULL, /* satisfied */ no_signal, /* signal */ no_get_fd, /* get_fd */ - directory_map_access, /* map_access */ + default_fd_map_access, /* map_access */ directory_lookup_name, /* lookup_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ @@ -123,15 +122,6 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_ return NULL; } -static unsigned int directory_map_access( struct object *obj, unsigned int access ) -{ - if (access & GENERIC_READ) access |= FILE_GENERIC_READ; - if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; - if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; - if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; - return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); -} - static void directory_destroy( struct object *obj ) { struct directory *dir = (struct directory *)obj; diff --git a/server/fd.c b/server/fd.c index d671a1cddc6..4779475ae23 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1710,6 +1710,16 @@ int default_fd_signaled( struct object *obj, struct thread *thread ) return ret; } +/* default map_access() routine for objects that behave like an fd */ +unsigned int default_fd_map_access( struct object *obj, unsigned int access ) +{ + if (access & GENERIC_READ) access |= FILE_GENERIC_READ; + if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; + if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; + if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); +} + int default_fd_get_poll_events( struct fd *fd ) { int events = 0; diff --git a/server/file.c b/server/file.c index a8152daaf2c..d65ff44f33a 100644 --- a/server/file.c +++ b/server/file.c @@ -65,7 +65,6 @@ static unsigned int generic_file_map_access( unsigned int access ); static void file_dump( struct object *obj, int verbose ); static struct fd *file_get_fd( struct object *obj ); -static unsigned int file_map_access( struct object *obj, unsigned int access ); static void file_destroy( struct object *obj ); static int file_get_poll_events( struct fd *fd ); @@ -82,7 +81,7 @@ static const struct object_ops file_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ file_get_fd, /* get_fd */ - file_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -122,7 +121,7 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in if ((file = alloc_object( &file_ops ))) { file->mode = st.st_mode; - file->access = file_map_access( &file->obj, access ); + file->access = default_fd_map_access( &file->obj, access ); if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj, FILE_SYNCHRONOUS_IO_NONALERT ))) { @@ -268,11 +267,6 @@ static unsigned int generic_file_map_access( unsigned int access ) return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } -static unsigned int file_map_access( struct object *obj, unsigned int access ) -{ - return generic_file_map_access( access ); -} - static void file_destroy( struct object *obj ) { struct file *file = (struct file *)obj; diff --git a/server/file.h b/server/file.h index d56aad037fe..823cc2cd2f4 100644 --- a/server/file.h +++ b/server/file.h @@ -75,6 +75,7 @@ extern void unlock_fd( struct fd *fd, file_pos_t offset, file_pos_t count ); extern void set_fd_signaled( struct fd *fd, int signaled ); extern int default_fd_signaled( struct object *obj, struct thread *thread ); +extern unsigned int default_fd_map_access( struct object *obj, unsigned int access ); extern int default_fd_get_poll_events( struct fd *fd ); extern void default_poll_event( struct fd *fd, int event ); extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); diff --git a/server/handle.c b/server/handle.c index 4b35e8b346b..65b4205d24c 100644 --- a/server/handle.c +++ b/server/handle.c @@ -588,3 +588,95 @@ DECL_HANDLER(get_object_info) reply->ref_count = obj->refcount; release_object( obj ); } + +DECL_HANDLER(set_security_object) +{ + data_size_t sd_size = get_req_data_size(); + const struct security_descriptor *sd = get_req_data(); + struct object *obj; + unsigned int access = 0; + + if (!sd_is_valid( sd, sd_size )) + { + set_error( STATUS_ACCESS_VIOLATION ); + return; + } + + if (req->security_info & OWNER_SECURITY_INFORMATION || + req->security_info & GROUP_SECURITY_INFORMATION) + access |= WRITE_OWNER; + if (req->security_info & SACL_SECURITY_INFORMATION) + access |= ACCESS_SYSTEM_SECURITY; + if (req->security_info & DACL_SECURITY_INFORMATION) + access |= WRITE_DAC; + + if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return; + + set_object_sd( obj, sd, req->security_info ); + release_object( obj ); +} + +DECL_HANDLER(get_security_object) +{ + const struct security_descriptor *sd; + struct object *obj; + unsigned int access = READ_CONTROL; + struct security_descriptor req_sd; + int present; + const SID *owner, *group; + const ACL *sacl, *dacl; + + if (req->security_info & SACL_SECURITY_INFORMATION) + access |= ACCESS_SYSTEM_SECURITY; + + if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return; + + sd = obj->sd; + if (sd) + { + req_sd.control = sd->control & ~SE_SELF_RELATIVE; + + owner = sd_get_owner( sd ); + if (req->security_info & OWNER_SECURITY_INFORMATION) + req_sd.owner_len = sd->owner_len; + + group = sd_get_group( sd ); + if (req->security_info & GROUP_SECURITY_INFORMATION) + req_sd.group_len = sd->group_len; + + req_sd.control |= SE_SACL_PRESENT; + sacl = sd_get_sacl( sd, &present ); + if (req->security_info & SACL_SECURITY_INFORMATION && present) + req_sd.sacl_len = sd->sacl_len; + else + req_sd.sacl_len = 0; + + req_sd.control |= SE_DACL_PRESENT; + dacl = sd_get_dacl( sd, &present ); + if (req->security_info & DACL_SECURITY_INFORMATION && present) + req_sd.dacl_len = sd->dacl_len; + else + req_sd.dacl_len = 0; + + reply->sd_len = sizeof(req_sd) + req_sd.owner_len + req_sd.group_len + + req_sd.sacl_len + req_sd.dacl_len; + if (reply->sd_len <= get_reply_max_size()) + { + char *ptr = set_reply_data_size(reply->sd_len); + + memcpy( ptr, &req_sd, sizeof(req_sd) ); + ptr += sizeof(req_sd); + memcpy( ptr, owner, req_sd.owner_len ); + ptr += req_sd.owner_len; + memcpy( ptr, group, req_sd.group_len ); + ptr += req_sd.group_len; + memcpy( ptr, sacl, req_sd.sacl_len ); + ptr += req_sd.sacl_len; + memcpy( ptr, dacl, req_sd.dacl_len ); + } + else + set_error(STATUS_BUFFER_TOO_SMALL); + } + + release_object( obj ); +} diff --git a/server/named_pipe.c b/server/named_pipe.c index 39dd10a8d48..e39f85a99bf 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -130,9 +130,6 @@ static const struct object_ops named_pipe_ops = named_pipe_destroy /* destroy */ }; -/* functions common to server and client */ -static unsigned int pipe_map_access( struct object *obj, unsigned int access ); - /* server end functions */ static void pipe_server_dump( struct object *obj, int verbose ); static struct fd *pipe_server_get_fd( struct object *obj ); @@ -152,7 +149,7 @@ static const struct object_ops pipe_server_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_server_get_fd, /* get_fd */ - pipe_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -188,7 +185,7 @@ static const struct object_ops pipe_client_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_client_get_fd, /* get_fd */ - pipe_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -357,15 +354,6 @@ static void do_disconnect( struct pipe_server *server ) server->fd = NULL; } -static unsigned int pipe_map_access( struct object *obj, unsigned int access ) -{ - if (access & GENERIC_READ) access |= FILE_GENERIC_READ; - if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; - if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; - if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; - return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); -} - static void pipe_server_destroy( struct object *obj) { struct pipe_server *server = (struct pipe_server *)obj; diff --git a/server/object.c b/server/object.c index 7f44b71ed1d..d10b878f062 100644 --- a/server/object.c +++ b/server/object.c @@ -34,8 +34,10 @@ #include "winternl.h" #include "file.h" +#include "process.h" #include "thread.h" #include "unicode.h" +#include "security.h" struct object_name @@ -365,6 +367,93 @@ unsigned int no_map_access( struct object *obj, unsigned int access ) return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } +void set_object_sd( struct object *obj, const struct security_descriptor *sd, + unsigned int set_info ) +{ + struct security_descriptor new_sd, *new_sd_ptr; + int present; + const SID *owner, *group; + const ACL *sacl, *dacl; + char *ptr; + + if (!set_info) return; + + new_sd.control = sd->control & ~SE_SELF_RELATIVE; + + owner = sd_get_owner( sd ); + if (set_info & OWNER_SECURITY_INFORMATION && owner) + new_sd.owner_len = sd->owner_len; + else + { + owner = token_get_user( current->process->token ); + new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]); + new_sd.control |= SE_OWNER_DEFAULTED; + } + + group = sd_get_group( sd ); + if (set_info & GROUP_SECURITY_INFORMATION && group) + new_sd.group_len = sd->group_len; + else + { + group = token_get_primary_group( current->process->token ); + new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]); + new_sd.control |= SE_GROUP_DEFAULTED; + } + + new_sd.control |= SE_SACL_PRESENT; + sacl = sd_get_sacl( sd, &present ); + if (set_info & SACL_SECURITY_INFORMATION && present) + new_sd.sacl_len = sd->sacl_len; + else + { + if (obj->sd) sacl = sd_get_sacl( obj->sd, &present ); + + if (obj->sd && present) + new_sd.sacl_len = obj->sd->sacl_len; + else + { + new_sd.sacl_len = 0; + new_sd.control |= SE_SACL_DEFAULTED; + } + } + + new_sd.control |= SE_DACL_PRESENT; + dacl = sd_get_dacl( sd, &present ); + if (set_info & DACL_SECURITY_INFORMATION && present) + new_sd.dacl_len = sd->dacl_len; + else + { + if (obj->sd) dacl = sd_get_dacl( obj->sd, &present ); + + if (obj->sd && present) + new_sd.dacl_len = obj->sd->dacl_len; + else + { + dacl = token_get_default_dacl( current->process->token ); + new_sd.dacl_len = dacl->AclSize; + new_sd.control |= SE_DACL_DEFAULTED; + } + } + + ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len + + new_sd.sacl_len + new_sd.dacl_len ); + if (!ptr) return; + new_sd_ptr = (struct security_descriptor*)ptr; + + memcpy( ptr, &new_sd, sizeof(new_sd) ); + ptr += sizeof(new_sd); + memcpy( ptr, owner, new_sd.owner_len ); + ptr += new_sd.owner_len; + memcpy( ptr, group, new_sd.group_len ); + ptr += new_sd.group_len; + memcpy( ptr, sacl, new_sd.sacl_len ); + ptr += new_sd.sacl_len; + memcpy( ptr, dacl, new_sd.dacl_len ); + + free( obj->sd ); + obj->sd = new_sd_ptr; +} + struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) { diff --git a/server/object.h b/server/object.h index ffb248687ff..c40b633fdbe 100644 --- a/server/object.h +++ b/server/object.h @@ -127,6 +127,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_signal( struct object *obj, unsigned int access ); extern struct fd *no_get_fd( struct object *obj ); extern unsigned int no_map_access( struct object *obj, unsigned int access ); +extern void set_object_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ); extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); diff --git a/server/protocol.def b/server/protocol.def index dfb6acccbe6..1a7aa4fc748 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2825,6 +2825,14 @@ enum message_type VARARG(sd,security_descriptor); /* security descriptor to set */ @END +@REQ(get_security_object) + obj_handle_t handle; /* handle to the object */ + unsigned int security_info; /* which parts of security descriptor to get */ +@REPLY + unsigned int sd_len; /* buffer size needed for sd */ + VARARG(sd,security_descriptor); /* retrieved security descriptor */ +@END + /* Create a mailslot */ @REQ(create_mailslot) unsigned int access; /* wanted access rights */ diff --git a/server/request.h b/server/request.h index af59fd4f157..ca9b969b126 100644 --- a/server/request.h +++ b/server/request.h @@ -319,6 +319,7 @@ DECL_HANDLER(access_check); DECL_HANDLER(get_token_user); DECL_HANDLER(get_token_groups); DECL_HANDLER(set_security_object); +DECL_HANDLER(get_security_object); DECL_HANDLER(create_mailslot); DECL_HANDLER(set_mailslot_info); DECL_HANDLER(create_directory); @@ -556,6 +557,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_token_user, (req_handler)req_get_token_groups, (req_handler)req_set_security_object, + (req_handler)req_get_security_object, (req_handler)req_create_mailslot, (req_handler)req_set_mailslot_info, (req_handler)req_create_directory, diff --git a/server/security.h b/server/security.h index f0c1b8c8aaf..88b437d6c49 100644 --- a/server/security.h +++ b/server/security.h @@ -41,6 +41,9 @@ extern const LUID SeCreateGlobalPrivilege; extern const PSID security_interactive_sid; + +/* token functions */ + extern struct token *token_create_admin(void); extern struct token *token_duplicate( struct token *src_token, unsigned primary, SECURITY_IMPERSONATION_LEVEL impersonation_level ); @@ -48,6 +51,9 @@ extern int token_check_privileges( struct token *token, int all_required, const LUID_AND_ATTRIBUTES *reqprivs, unsigned int count, LUID_AND_ATTRIBUTES *usedprivs); extern const ACL *token_get_default_dacl( struct token *token ); +extern const SID *token_get_user( struct token *token ); +extern const SID *token_get_primary_group( struct token *token ); + extern void security_set_thread_token( struct thread *thread, obj_handle_t handle ); extern int check_object_access( struct object *obj, unsigned int *access ); @@ -60,3 +66,50 @@ static inline int thread_single_check_privilege( struct thread *thread, const LU return token_check_privileges( token, TRUE, &privs, 1, NULL ); } + + +/* security descriptor helper functions */ + +extern int sd_is_valid( const struct security_descriptor *sd, data_size_t size ); + +/* gets the discretionary access control list from a security descriptor */ +static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present ) +{ + *present = (sd->control & SE_DACL_PRESENT ? TRUE : FALSE); + + if (sd->dacl_len) + return (const ACL *)((const char *)(sd + 1) + + sd->owner_len + sd->group_len + sd->sacl_len); + else + return NULL; +} + +/* gets the system access control list from a security descriptor */ +static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present ) +{ + *present = (sd->control & SE_SACL_PRESENT ? TRUE : FALSE); + + if (sd->sacl_len) + return (const ACL *)((const char *)(sd + 1) + + sd->owner_len + sd->group_len); + else + return NULL; +} + +/* gets the owner from a security descriptor */ +static inline const SID *sd_get_owner( const struct security_descriptor *sd ) +{ + if (sd->owner_len) + return (const SID *)(sd + 1); + else + return NULL; +} + +/* gets the primary group from a security descriptor */ +static inline const SID *sd_get_group( const struct security_descriptor *sd ) +{ + if (sd->group_len) + return (const SID *)((const char *)(sd + 1) + sd->owner_len); + else + return NULL; +} diff --git a/server/serial.c b/server/serial.c index 628db5a36d3..5a1e3cabd04 100644 --- a/server/serial.c +++ b/server/serial.c @@ -58,7 +58,6 @@ static void serial_dump( struct object *obj, int verbose ); static struct fd *serial_get_fd( struct object *obj ); -static unsigned int serial_map_access( struct object *obj, unsigned int access ); static void serial_destroy(struct object *obj); static enum server_fd_type serial_get_fd_type( struct fd *fd ); @@ -94,7 +93,7 @@ static const struct object_ops serial_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ serial_get_fd, /* get_fd */ - serial_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -145,15 +144,6 @@ static struct fd *serial_get_fd( struct object *obj ) return (struct fd *)grab_object( serial->fd ); } -static unsigned int serial_map_access( struct object *obj, unsigned int access ) -{ - if (access & GENERIC_READ) access |= FILE_GENERIC_READ; - if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; - if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; - if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; - return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); -} - static void serial_destroy( struct object *obj) { struct serial *serial = (struct serial *)obj; diff --git a/server/sock.c b/server/sock.c index d7c1e68a756..0694c51fa2f 100644 --- a/server/sock.c +++ b/server/sock.c @@ -90,7 +90,6 @@ struct sock static void sock_dump( struct object *obj, int verbose ); static int sock_signaled( struct object *obj, struct thread *thread ); static struct fd *sock_get_fd( struct object *obj ); -static unsigned int sock_map_access( struct object *obj, unsigned int access ); static void sock_destroy( struct object *obj ); static int sock_get_poll_events( struct fd *fd ); @@ -113,7 +112,7 @@ static const struct object_ops sock_ops = no_satisfied, /* satisfied */ no_signal, /* signal */ sock_get_fd, /* get_fd */ - sock_map_access, /* map_access */ + default_fd_map_access, /* map_access */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ @@ -459,15 +458,6 @@ static int sock_signaled( struct object *obj, struct thread *thread ) return check_fd_events( sock->fd, sock_get_poll_events( sock->fd ) ) != 0; } -static unsigned int sock_map_access( struct object *obj, unsigned int access ) -{ - if (access & GENERIC_READ) access |= FILE_GENERIC_READ; - if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; - if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; - if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; - return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); -} - static int sock_get_poll_events( struct fd *fd ) { struct sock *sock = get_fd_user( fd ); diff --git a/server/token.c b/server/token.c index 655e597dd4a..00cd6db87ab 100644 --- a/server/token.c +++ b/server/token.c @@ -248,51 +248,9 @@ static int acl_is_valid( const ACL *acl, data_size_t size ) return TRUE; } -/* gets the discretionary access control list from a security descriptor */ -static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present ) -{ - *present = (sd->control & SE_DACL_PRESENT ? TRUE : FALSE); - - if (sd->dacl_len) - return (const ACL *)((const char *)(sd + 1) + - sd->owner_len + sd->group_len + sd->sacl_len); - else - return NULL; -} - -/* gets the system access control list from a security descriptor */ -static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present ) -{ - *present = (sd->control & SE_SACL_PRESENT ? TRUE : FALSE); - - if (sd->sacl_len) - return (const ACL *)((const char *)(sd + 1) + - sd->owner_len + sd->group_len); - else - return NULL; -} - -/* gets the owner from a security descriptor */ -static inline const SID *sd_get_owner( const struct security_descriptor *sd ) -{ - if (sd->owner_len) - return (const SID *)(sd + 1); - else - return NULL; -} - -/* gets the primary group from a security descriptor */ -static inline const SID *sd_get_group( const struct security_descriptor *sd ) -{ - if (sd->group_len) - return (const SID *)((const char *)(sd + 1) + sd->owner_len); - else - return NULL; -} - /* checks whether all members of a security descriptor fit inside the size * of memory specified */ -static int sd_is_valid( const struct security_descriptor *sd, data_size_t size ) +int sd_is_valid( const struct security_descriptor *sd, data_size_t size ) { size_t offset = sizeof(struct security_descriptor); const SID *group; @@ -586,7 +544,7 @@ static ACL *create_default_dacl( const SID *user ) default_dacl = mem_alloc( default_dacl_size ); if (!default_dacl) return NULL; - default_dacl->AclRevision = MAX_ACL_REVISION; + default_dacl->AclRevision = ACL_REVISION; default_dacl->Sbz1 = 0; default_dacl->AclSize = default_dacl_size; default_dacl->AceCount = 2; @@ -984,91 +942,14 @@ const ACL *token_get_default_dacl( struct token *token ) return token->default_dacl; } -static void set_object_sd( struct object *obj, const struct security_descriptor *sd, - unsigned int set_info ) +const SID *token_get_user( struct token *token ) { - struct security_descriptor new_sd, *pnew_sd; - int present; - const SID *owner, *group; - const ACL *sacl, *dacl; - char *ptr; - - if (!set_info) return; - - new_sd.control = sd->control & ~SE_SELF_RELATIVE; - - owner = sd_get_owner( sd ); - if (set_info & OWNER_SECURITY_INFORMATION && owner) - new_sd.owner_len = sd->owner_len; - else - { - owner = current->process->token->user; - new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]); - new_sd.control |= SE_OWNER_DEFAULTED; - } - - group = sd_get_group( sd ); - if (set_info & GROUP_SECURITY_INFORMATION && group) - new_sd.group_len = sd->group_len; - else - { - group = current->process->token->primary_group; - new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]); - new_sd.control |= SE_GROUP_DEFAULTED; - } - - new_sd.control |= SE_SACL_PRESENT; - sacl = sd_get_sacl( sd, &present ); - if (set_info & SACL_SECURITY_INFORMATION && present) - new_sd.sacl_len = sd->sacl_len; - else - { - if (obj->sd) sacl = sd_get_sacl( obj->sd, &present ); - - if (obj->sd && present) - new_sd.sacl_len = obj->sd->sacl_len; - else - { - new_sd.sacl_len = 0; - new_sd.control |= SE_SACL_DEFAULTED; - } - } - - new_sd.control |= SE_DACL_PRESENT; - dacl = sd_get_dacl( sd, &present ); - if (set_info & DACL_SECURITY_INFORMATION && present) - new_sd.dacl_len = sd->dacl_len; - else - { - if (obj->sd) dacl = sd_get_dacl( obj->sd, &present ); - - if (obj->sd && present) - new_sd.dacl_len = obj->sd->dacl_len; - else - { - dacl = token_get_default_dacl( current->process->token ); - new_sd.dacl_len = dacl->AclSize; - new_sd.control |= SE_DACL_DEFAULTED; - } - } + return token->user; +} - ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len + - new_sd.sacl_len + new_sd.dacl_len ); - if (!ptr) return; - pnew_sd = (struct security_descriptor*)ptr; - - memcpy( ptr, &new_sd, sizeof(new_sd) ); - ptr += sizeof(new_sd); - memcpy( ptr, owner, new_sd.owner_len ); - ptr += new_sd.owner_len; - memcpy( ptr, group, new_sd.group_len ); - ptr += new_sd.group_len; - memcpy( ptr, sacl, new_sd.sacl_len ); - ptr += new_sd.sacl_len; - memcpy( ptr, dacl, new_sd.dacl_len ); - - free( obj->sd ); - obj->sd = pnew_sd; +const SID *token_get_primary_group( struct token *token ) +{ + return token->primary_group; } int check_object_access(struct object *obj, unsigned int *access) @@ -1442,30 +1323,3 @@ DECL_HANDLER(get_token_statistics) release_object( token ); } } - -DECL_HANDLER(set_security_object) -{ - data_size_t sd_size = get_req_data_size(); - const struct security_descriptor *sd = get_req_data(); - struct object *obj; - unsigned int access = 0; - - if (!sd_is_valid( sd, sd_size )) - { - set_error( STATUS_ACCESS_VIOLATION ); - return; - } - - if (req->security_info & OWNER_SECURITY_INFORMATION || - req->security_info & GROUP_SECURITY_INFORMATION) - access |= WRITE_OWNER; - if (req->security_info & SACL_SECURITY_INFORMATION) - access |= ACCESS_SYSTEM_SECURITY; - if (req->security_info & DACL_SECURITY_INFORMATION) - access |= WRITE_DAC; - - if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return; - - set_object_sd( obj, sd, req->security_info ); - release_object( obj ); -} diff --git a/server/trace.c b/server/trace.c index bcd5b46c420..fac142a147f 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3413,6 +3413,19 @@ static void dump_set_security_object_request( const struct set_security_object_r dump_varargs_security_descriptor( cur_size ); } +static void dump_get_security_object_request( const struct get_security_object_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " security_info=%08x", req->security_info ); +} + +static void dump_get_security_object_reply( const struct get_security_object_reply *req ) +{ + fprintf( stderr, " sd_len=%08x,", req->sd_len ); + fprintf( stderr, " sd=" ); + dump_varargs_security_descriptor( cur_size ); +} + static void dump_create_mailslot_request( const struct create_mailslot_request *req ) { fprintf( stderr, " access=%08x,", req->access ); @@ -3908,6 +3921,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_token_user_request, (dump_func)dump_get_token_groups_request, (dump_func)dump_set_security_object_request, + (dump_func)dump_get_security_object_request, (dump_func)dump_create_mailslot_request, (dump_func)dump_set_mailslot_info_request, (dump_func)dump_create_directory_request, @@ -4142,6 +4156,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_token_user_reply, (dump_func)dump_get_token_groups_reply, (dump_func)0, + (dump_func)dump_get_security_object_reply, (dump_func)dump_create_mailslot_reply, (dump_func)dump_set_mailslot_info_reply, (dump_func)dump_create_directory_reply, @@ -4376,6 +4391,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_token_user", "get_token_groups", "set_security_object", + "get_security_object", "create_mailslot", "set_mailslot_info", "create_directory", diff --git a/tools/widl/client.c b/tools/widl/client.c index 86ead201daa..1f35c3eb548 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -109,7 +109,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) } } - write_type_left(client, def->type); + write_type_decl_left(client, def->type); if (needs_space_after(def->type)) fprintf(client, " "); write_prefix_name(client, prefix_client, def); @@ -130,7 +130,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) if (!is_void(def->type)) { print_client(""); - write_type_left(client, def->type); + write_type_decl_left(client, def->type); fprintf(client, " _RetVal;\n"); } diff --git a/tools/widl/header.c b/tools/widl/header.c index ded4c1888ac..2643f49198e 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -156,7 +156,7 @@ static void write_field(FILE *h, var_t *v) } } indent(h, 0); - write_type(h, v->type, TRUE, "%s", name); + write_type_def_or_decl(h, v->type, TRUE, "%s", name); fprintf(h, ";\n"); } } @@ -193,19 +193,21 @@ int needs_space_after(type_t *t) || (!is_ptr(t) && (!is_conformant_array(t) || t->declarray))); } -void write_type_left(FILE *h, type_t *t) +void write_type_left(FILE *h, type_t *t, int declonly) { + if (!h) return; + if (t->is_const) fprintf(h, "const "); if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name); - else if (t->declarray) write_type_left(h, t->ref); + else if (t->declarray) write_type_left(h, t->ref, declonly); else { if (t->sign > 0) fprintf(h, "signed "); else if (t->sign < 0) fprintf(h, "unsigned "); switch (t->type) { case RPC_FC_ENUM16: case RPC_FC_ENUM32: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "enum %s {\n", t->name); else fprintf(h, "enum {\n"); t->written = TRUE; @@ -214,7 +216,7 @@ void write_type_left(FILE *h, type_t *t) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "enum %s", t->name); + else fprintf(h, "enum %s", t->name ? t->name : ""); break; case RPC_FC_STRUCT: case RPC_FC_CVSTRUCT: @@ -223,7 +225,7 @@ void write_type_left(FILE *h, type_t *t) case RPC_FC_PSTRUCT: case RPC_FC_BOGUS_STRUCT: case RPC_FC_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "struct %s {\n", t->name); else fprintf(h, "struct {\n"); t->written = TRUE; @@ -232,10 +234,10 @@ void write_type_left(FILE *h, type_t *t) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "struct %s", t->name); + else fprintf(h, "struct %s", t->name ? t->name : ""); break; case RPC_FC_NON_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "union %s {\n", t->name); else fprintf(h, "union {\n"); t->written = TRUE; @@ -244,7 +246,7 @@ void write_type_left(FILE *h, type_t *t) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "union %s", t->name); + else fprintf(h, "union %s", t->name ? t->name : ""); break; case RPC_FC_RP: case RPC_FC_UP: @@ -253,7 +255,7 @@ void write_type_left(FILE *h, type_t *t) case RPC_FC_CARRAY: case RPC_FC_CVARRAY: case RPC_FC_BOGUS_ARRAY: - write_type_left(h, t->ref); + write_type_left(h, t->ref, declonly); fprintf(h, "%s*", needs_space_after(t->ref) ? " " : ""); break; default: @@ -264,6 +266,8 @@ void write_type_left(FILE *h, type_t *t) void write_type_right(FILE *h, type_t *t, int is_field) { + if (!h) return; + if (t->declarray) { if (is_conformant_array(t)) { fprintf(h, "[%s]", is_field ? "1" : ""); @@ -274,20 +278,41 @@ void write_type_right(FILE *h, type_t *t, int is_field) } } -void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...) +void write_type_v(FILE *h, type_t *t, int is_field, int declonly, + const char *fmt, va_list args) { - write_type_left(h, t); + if (!h) return; + + write_type_left(h, t, declonly); if (fmt) { - va_list args; - va_start(args, fmt); if (needs_space_after(t)) fprintf(h, " "); vfprintf(h, fmt, args); - va_end(args); } write_type_right(h, t, is_field); } +void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + write_type_v(f, t, field, FALSE, fmt, args); + va_end(args); +} + +void write_type_decl(FILE *f, type_t *t, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + write_type_v(f, t, FALSE, TRUE, fmt, args); + va_end(args); +} + +void write_type_decl_left(FILE *f, type_t *t) +{ + write_type_left(f, t, TRUE); +} + static int user_type_registered(const char *name) { user_type_t *ut; @@ -373,7 +398,7 @@ void write_context_handle_rundowns(void) void write_typedef(type_t *type) { fprintf(header, "typedef "); - write_type(header, type->orig, FALSE, "%s", type->name); + write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name); fprintf(header, ";\n"); } @@ -414,13 +439,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets) break; case EXPR_CAST: fprintf(h, "("); - write_type(h, e->u.tref, FALSE, NULL); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); write_expr(h, e->ref, 1); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); - write_type(h, e->u.tref, FALSE, NULL); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); break; case EXPR_SHL: @@ -469,7 +494,7 @@ void write_constdef(const var_t *v) void write_externdef(const var_t *v) { fprintf(header, "extern const "); - write_type(header, v->type, FALSE, "%s", v->name); + write_type_def_or_decl(header, v->type, FALSE, "%s", v->name); fprintf(header, ";\n\n"); } @@ -595,7 +620,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i } if (arg->args) { - write_type_left(h, arg->type); + write_type_decl_left(h, arg->type); fprintf(h, " (STDMETHODCALLTYPE *"); write_name(h,arg); fprintf(h, ")("); @@ -603,7 +628,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i fprintf(h, ")"); } else - write_type(h, arg->type, FALSE, "%s", arg->name); + write_type_decl(h, arg->type, "%s", arg->name); count++; } if (do_indent) indentation--; @@ -621,7 +646,7 @@ static void write_cpp_method_def(const type_t *iface) if (!is_callas(def->attrs)) { indent(header, 0); fprintf(header, "virtual "); - write_type_left(header, def->type); + write_type_decl_left(header, def->type); fprintf(header, " STDMETHODCALLTYPE "); write_name(header, def); fprintf(header, "(\n"); @@ -646,7 +671,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name) const var_t *def = cur->def; if (!is_callas(def->attrs)) { indent(header, 0); - write_type_left(header, def->type); + write_type_decl_left(header, def->type); fprintf(header, " (STDMETHODCALLTYPE *"); write_name(header, def); fprintf(header, ")(\n"); @@ -679,7 +704,7 @@ static void write_method_proto(const type_t *iface) if (!is_local(def->attrs)) { /* proxy prototype */ - write_type_left(header, def->type); + write_type_decl_left(header, def->type); fprintf(header, " CALLBACK %s_", iface->name); write_name(header, def); fprintf(header, "_Proxy(\n"); @@ -701,14 +726,14 @@ static void write_method_proto(const type_t *iface) if (&m->entry != iface->funcs) { const var_t *mdef = m->def; /* proxy prototype - use local prototype */ - write_type_left(header, mdef->type); + write_type_decl_left(header, mdef->type); fprintf(header, " CALLBACK %s_", iface->name); write_name(header, mdef); fprintf(header, "_Proxy(\n"); write_args(header, m->args, iface->name, 1, TRUE); fprintf(header, ");\n"); /* stub prototype - use remotable prototype */ - write_type_left(header, def->type); + write_type_decl_left(header, def->type); fprintf(header, " __RPC_STUB %s_", iface->name); write_name(header, mdef); fprintf(header, "_Stub(\n"); @@ -727,7 +752,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c var_t *def = fun->def; /* FIXME: do we need to handle call_as? */ - write_type_left(header, def->type); + write_type_decl_left(header, def->type); fprintf(header, " "); write_prefix_name(header, prefix, def); fprintf(header, "(\n"); diff --git a/tools/widl/header.h b/tools/widl/header.h index 3c6a124b7dd..3937971e621 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -32,9 +32,11 @@ extern int is_conformant_array(const type_t *t); extern void write_name(FILE *h, const var_t *v); extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v); extern const char* get_name(const var_t *v); -extern void write_type_left(FILE *h, type_t *t); +extern void write_type_left(FILE *h, type_t *t, int declonly); extern void write_type_right(FILE *h, type_t *t, int is_field); -extern void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...); +extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *fmt, ...); +extern void write_type_decl(FILE *f, type_t *t, const char *fmt, ...); +extern void write_type_decl_left(FILE *f, type_t *t); extern int needs_space_after(type_t *t); extern int is_object(const attr_list_t *list); extern int is_local(const attr_list_t *list); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index c4fc2c9f4f8..8799e89b762 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -65,6 +65,8 @@ # endif #endif +unsigned char pointer_default = RPC_FC_UP; + typedef struct list typelist_t; struct typenode { type_t *type; @@ -92,7 +94,7 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp static type_t *make_type(unsigned char type, type_t *ref); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr); +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); static var_list_t *append_var(var_list_t *list, var_t *var); @@ -325,20 +327,20 @@ statement: ';' {} | constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } | cppquote {} | enumdef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); + write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } | import {} | structdef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); + write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } | typedef ';' {} | uniondef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); + write_type_def_or_decl(header, $1, FALSE, NULL); fprintf(header, ";\n\n"); } } @@ -380,21 +382,21 @@ args: arg { check_arg($1); $$ = append_var( NULL, $1 ); } /* split into two rules to get bison to resolve a tVOID conflict */ arg: attributes type pident array { $$ = $3->var; $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4); + set_type($$, $2, $3->ptr_level, $4, TRUE); free($3); } | type pident array { $$ = $2->var; - set_type($$, $1, $2->ptr_level, $3); + set_type($$, $1, $2->ptr_level, $3, TRUE); free($2); } | attributes type pident '(' m_args ')' { $$ = $3->var; $$->attrs = $1; - set_type($$, $2, $3->ptr_level - 1, NULL); + set_type($$, $2, $3->ptr_level - 1, NULL, TRUE); free($3); $$->args = $5; } | type pident '(' m_args ')' { $$ = $2->var; - set_type($$, $1, $2->ptr_level - 1, NULL); + set_type($$, $1, $2->ptr_level - 1, NULL, TRUE); free($2); $$->args = $4; } @@ -523,7 +525,7 @@ case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr( ; constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); - set_type($$, $2, 0, NULL); + set_type($$, $2, 0, NULL, FALSE); $$->eval = $5; } ; @@ -616,7 +618,7 @@ expr_const: expr { $$ = $1; ; externdef: tEXTERN tCONST type ident { $$ = $4; - set_type($$, $3, 0, NULL); + set_type($$, $3, 0, NULL, FALSE); } ; @@ -632,7 +634,7 @@ field: s_field ';' { $$ = $1; } s_field: m_attributes type pident array { $$ = $3->var; $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4); + set_type($$, $2, $3->ptr_level, $4, FALSE); free($3); } ; @@ -641,7 +643,7 @@ funcdef: m_attributes type callconv pident '(' m_args ')' { var_t *v = $4->var; v->attrs = $1; - set_type(v, $2, $4->ptr_level, NULL); + set_type(v, $2, $4->ptr_level, NULL, FALSE); free($4); $$ = make_func(v, $6); if (is_attr(v->attrs, ATTR_IN)) { @@ -1262,20 +1264,25 @@ static type_t *make_type(unsigned char type, type_t *ref) return t; } -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, + int top) { expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); - int ptr_type = get_attrv(v->attrs, ATTR_POINTERTYPE); + int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); + int ptr_type = ptr_attr; int sizeless, has_varconf; expr_t *dim; type_t *atype, **ptype; v->type = type; + if (!ptr_type && top) + ptr_type = RPC_FC_RP; + for ( ; 0 < ptr_level; --ptr_level) { - v->type = make_type(RPC_FC_RP, v->type); + v->type = make_type(pointer_default, v->type); if (ptr_level == 1 && ptr_type && !arr) { v->type->type = ptr_type; @@ -1287,11 +1294,14 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) { if (is_ptr(v->type)) { - v->type = duptype(v->type, 1); - v->type->type = ptr_type; + if (v->type->type != ptr_type) + { + v->type = duptype(v->type, 1); + v->type->type = ptr_type; + } } - else if (!arr) - error("%s: pointer attribute applied to non-pointer type", v->name); + else if (!arr && ptr_attr) + error("%s: pointer attribute applied to non-pointer type\n", v->name); } sizeless = FALSE; @@ -1309,7 +1319,7 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) error("%s: array dimension must be positive\n", v->name); if (0xffffffffuL / size < (unsigned long) dim->cval) - error("%s: total array size is too large", v->name); + error("%s: total array size is too large\n", v->name); else if (0xffffuL < size * dim->cval) v->type = make_type(RPC_FC_LGFARRAY, v->type); else @@ -1504,7 +1514,7 @@ static type_t *make_safearray(type_t *type) { type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); sa->ref = type; - return make_type(RPC_FC_FP, sa); + return make_type(pointer_default, sa); } #define HASHMAX 64 @@ -1628,7 +1638,7 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a int cptr = pident->ptr_level; if (cptr > ptrc) { while (cptr > ptrc) { - cur = ptr = make_type(RPC_FC_RP, cur); + cur = ptr = make_type(pointer_default, cur); ptrc++; } } else { diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 4911caf2b66..98d4ddb1f31 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -255,7 +255,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx, int has_ret = !is_void(def->type); indent = 0; - write_type_left(proxy, def->type); + write_type_decl_left(proxy, def->type); print_proxy( " STDMETHODCALLTYPE %s_", iface->name); write_name(proxy, def); print_proxy( "_Proxy(\n"); @@ -266,7 +266,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx, /* local variables */ if (has_ret) { print_proxy( "" ); - write_type_left(proxy, def->type); + write_type_decl_left(proxy, def->type); print_proxy( " _RetVal;\n"); } print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); diff --git a/tools/widl/server.c b/tools/widl/server.c index f708d252889..8c9345c90f1 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -187,7 +187,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) if (is_context_handle(var->type)) { print_server("("); - write_type_left(server, var->type); + write_type_decl_left(server, var->type); fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name); } else diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 88bb7c9d692..ba2c98354f0 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -868,11 +868,18 @@ static unsigned int write_simple_pointer(FILE *file, const type_t *type) return 4; } +static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff) +{ + print_file(file, 0, "/* %u (", tfsoff); + write_type_decl(file, t, NULL); + print_file(file, 0, ") */\n"); +} + static size_t write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestring_offset) { unsigned int offset = *typestring_offset; - print_file(file, 0, "/* %d */\n", offset); + print_start_tfs_comment(file, type, offset); update_tfsoff(type, offset, file); if (type->ref->typestring_offset) @@ -904,7 +911,7 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) if (is_base_type(utype->type)) { absoff = *tfsoff; - print_file(file, 0, "/* %d */\n", absoff); + print_start_tfs_comment(file, utype, absoff); print_file(file, 2, "0x%x,\t/* %s */\n", utype->type, string_of_type(utype->type)); print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); *tfsoff += 2; @@ -925,7 +932,7 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) start = *tfsoff; update_tfsoff(type, start, file); - print_file(file, 0, "/* %d */\n", start); + print_start_tfs_comment(file, type, start); print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL); print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n", flags | (align - 1), align - 1, flags); @@ -1486,7 +1493,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type start_offset = *typestring_offset; update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %lu */\n", start_offset); + print_start_tfs_comment(file, type, start_offset); print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); *typestring_offset += 2; @@ -1611,7 +1618,7 @@ static void write_struct_members(FILE *file, const type_t *type, fc = RPC_FC_ALIGNM8; break; default: - error("write_struct_members: cannot align type %d", ft->type); + error("write_struct_members: cannot align type %d\n", ft->type); } print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); offset = (offset + (align - 1)) & ~(align - 1); @@ -1672,7 +1679,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type, start_offset = *tfsoff; update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); + print_start_tfs_comment(file, type, start_offset); print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", total_size, total_size); @@ -1825,7 +1832,7 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff) start_offset = *tfsoff; update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); + print_start_tfs_comment(file, type, start_offset); if (type->type == RPC_FC_ENCAPSULATED_UNION) { const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry); @@ -1926,7 +1933,7 @@ static size_t write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type, error("%s: interface %s missing UUID\n", __FUNCTION__, base->name); update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); + print_start_tfs_comment(file, type, start_offset); print_file(file, 2, "0x2f,\t/* FC_IP */\n"); print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n"); print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1); @@ -1987,24 +1994,10 @@ static size_t write_contexthandle_tfs(FILE *file, const type_t *type, return start_offset; } -static int get_ptr_attr(const type_t *t, int def_type) -{ - while (TRUE) - { - int ptr_attr = get_attrv(t->attrs, ATTR_POINTERTYPE); - if (ptr_attr) - return ptr_attr; - if (t->kind != TKIND_ALIAS) - return def_type; - t = t->orig; - } -} - static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func, type_t *type, const var_t *var, unsigned int *typeformat_offset) { - int pointer_type; size_t offset; if (is_context_handle(type)) @@ -2016,35 +2009,23 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f return type->typestring_offset; } - if (type == var->type) /* top-level pointers */ - { - int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (pointer_attr != 0 && !is_ptr(type) && !is_array(type)) - error("'%s': pointer attribute applied to non-pointer type\n", var->name); - - if (pointer_attr == 0) - pointer_attr = get_ptr_attr(type, RPC_FC_RP); - - pointer_type = pointer_attr; - } - else - pointer_type = get_ptr_attr(type, RPC_FC_UP); - if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING)) return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset); if (is_array(type)) { + int ptr_type; size_t off; off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset); - if (pointer_type != RPC_FC_RP) + ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + if (ptr_type && ptr_type != RPC_FC_RP) { unsigned int absoff = type->typestring_offset; short reloff = absoff - (*typeformat_offset + 2); off = *typeformat_offset; print_file(file, 0, "/* %d */\n", off); - print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", pointer_type, - string_of_type(pointer_type)); + print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, + string_of_type(ptr_type)); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", reloff, reloff, absoff); *typeformat_offset += 4; @@ -2094,8 +2075,8 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f if (is_base_type(base->type)) { print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", - pointer_type, (!in_attr && out_attr) ? 0x0C : 0x08, - string_of_type(pointer_type), + type->type, (!in_attr && out_attr) ? 0x0C : 0x08, + string_of_type(type->type), (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type)); print_file(file, indent, "0x5c, /* FC_PAD */\n"); @@ -2109,7 +2090,7 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset); if (file) fprintf(file, "/* %2u */\n", *typeformat_offset); - return write_pointer_only_tfs(file, var->attrs, pointer_type, + return write_pointer_only_tfs(file, var->attrs, type->type, !last_ptr(type) ? 0x10 : 0, offset, typeformat_offset); } @@ -2548,7 +2529,7 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, if (phase == PHASE_MARSHAL) { print_file(file, indent, "*("); - write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL); + write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); if (is_ptr(type)) fprintf(file, " *)_StubMsg.Buffer = *"); else @@ -2567,12 +2548,12 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, fprintf(file, " = ("); else fprintf(file, " = *("); - write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL); + write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); fprintf(file, " *)_StubMsg.Buffer;\n"); } print_file(file, indent, "_StubMsg.Buffer += sizeof("); - write_type(file, var->type, FALSE, NULL); + write_type_decl(file, var->type, NULL); fprintf(file, ");\n"); } @@ -2930,13 +2911,13 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets, break; case EXPR_CAST: fprintf(h, "("); - write_type(h, e->u.tref, FALSE, NULL); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); write_struct_expr(h, e->ref, 1, fields, structvar); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); - write_type(h, e->u.tref, FALSE, NULL); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); break; case EXPR_SHL: @@ -2987,7 +2968,7 @@ void declare_stub_args( FILE *file, int indent, const func_t *func ) if (!is_void(def->type)) { print_file(file, indent, ""); - write_type_left(file, def->type); + write_type_decl_left(file, def->type); fprintf(file, " _RetVal;\n"); } @@ -3010,12 +2991,12 @@ void declare_stub_args( FILE *file, int indent, const func_t *func ) if (!in_attr && !var->type->size_is && !is_string) { print_file(file, indent, ""); - write_type(file, var->type->ref, FALSE, "_W%u", i++); + write_type_decl(file, var->type->ref, "_W%u", i++); fprintf(file, ";\n"); } print_file(file, indent, ""); - write_type_left(file, var->type); + write_type_decl_left(file, var->type); fprintf(file, " "); if (var->type->declarray) { fprintf(file, "( *"); diff --git a/tools/wine.desktop b/tools/wine.desktop index ed09306ee03..ed4982b7990 100644 --- a/tools/wine.desktop +++ b/tools/wine.desktop @@ -1,8 +1,7 @@ [Desktop Entry] Type=Application -Encoding=UTF-8 Name=Wine Windows Emulator Name[de]=Wine Windows-Emulator Exec=wine %f -MimeType=application/x-ms-dos-executable;application/x-msdos-program;application/x-msdownload;application/exe;application/x-exe;application/dos-exe;vms/exe;application/x-winexe;application/msdos-windows;application/x-msdos-program;application/x-zip-compressed;application/x-executable +MimeType=application/x-ms-dos-executable;application/x-msdos-program;application/x-msdownload;application/exe;application/x-exe;application/dos-exe;vms/exe;application/x-winexe;application/msdos-windows;application/x-zip-compressed;application/x-executable; NoDisplay=true diff --git a/tools/wine.inf b/tools/wine.inf index cfad301d1cc..2676f161518 100644 --- a/tools/wine.inf +++ b/tools/wine.inf @@ -2230,6 +2230,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,olepro32.dll 11,,opengl32.dll 11,,progman.exe +11,,psapi.dll 11,,quartz.dll 11,,regsvr32.exe 11,,riched20.dll -- 2.11.4.GIT