From f490febc7730e26c679d9c2e8d7ed198ae027938 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Wed, 24 Oct 2007 18:33:49 +0200 Subject: [PATCH] push b050ca7325a6963904b6d1b5c83418c4773d1a5f --- .gitignore | 2 +- dlls/browseui/Makefile.in | 3 +- dlls/browseui/browseui.h | 2 + dlls/browseui/browseui_main.c | 5 +- dlls/browseui/progressdlg.c | 506 +++++++++++++++++++++++++++++++ dlls/browseui/regsvr.c | 7 + dlls/browseui/{browseui.h => resids.h} | 13 +- dlls/browseui/{browseui.h => rsrc.rc} | 13 +- dlls/browseui/{browseui.h => rsrc_En.rc} | 24 +- dlls/credui/credui.spec | 8 +- dlls/credui/credui_main.c | 40 +++ dlls/crypt32/cert.c | 82 +++++ dlls/crypt32/chain.c | 137 ++++++++- dlls/crypt32/crypt32.spec | 2 +- dlls/crypt32/tests/cert.c | 34 +++ dlls/cryptnet/cryptnet_main.c | 168 +++++++++- dlls/d3dx8/tests/math.c | 165 ++++++++++ dlls/gdi32/bidi.c | 26 +- dlls/gdi32/tests/font.c | 3 +- dlls/ntdll/tests/rtlstr.c | 16 +- dlls/oleaut32/usrmarshal.c | 22 ++ dlls/shlwapi/ordinal.c | 38 +-- dlls/shlwapi/shlwapi.spec | 6 +- include/d3dx8math.inl | 124 ++++++++ include/rpc.h | 4 + include/shlguid.h | 9 +- include/shlobj.h | 53 ++++ include/shlwapi.h | 4 +- programs/cmdlgtst/Ko.rc | 6 +- programs/winedbg/source.c | 4 +- programs/winhelp/hlpfile.c | 6 +- tools/widl/parser.l | 10 +- tools/widl/parser.y | 45 ++- tools/widl/proxy.c | 2 +- tools/widl/utils.c | 11 + tools/widl/utils.h | 1 + tools/wine.inf | 1 + 37 files changed, 1459 insertions(+), 143 deletions(-) create mode 100644 dlls/browseui/progressdlg.c copy dlls/browseui/{browseui.h => resids.h} (77%) copy dlls/browseui/{browseui.h => rsrc.rc} (77%) copy dlls/browseui/{browseui.h => rsrc_En.rc} (52%) diff --git a/.gitignore b/.gitignore index e64757cf4b7..8244db690a9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,10 +31,10 @@ dlls/avicap32/libavicap32.def dlls/avifil32/libavifil32.def dlls/avifil32/rsrc.res dlls/avifile.dll16 +dlls/browseui/rsrc.res dlls/browseui/tests/*.ok dlls/browseui/tests/browseui_crosstest.exe dlls/browseui/tests/testlist.c -dlls/browseui/version.res dlls/cabinet/cabinet.res dlls/cabinet/libcabinet.def dlls/cabinet/tests/*.ok diff --git a/dlls/browseui/Makefile.in b/dlls/browseui/Makefile.in index 9b97ff9f0ba..b48886d9ba6 100644 --- a/dlls/browseui/Makefile.in +++ b/dlls/browseui/Makefile.in @@ -10,9 +10,10 @@ EXTRADEFS = -DCOM_NO_WINDOWS_H C_SRCS = \ aclmulti.c \ browseui_main.c \ + progressdlg.c \ regsvr.c -RC_SRCS = version.rc +RC_SRCS = rsrc.rc @MAKE_DLL_RULES@ diff --git a/dlls/browseui/browseui.h b/dlls/browseui/browseui.h index 2f44ac74914..74fd2d789bc 100644 --- a/dlls/browseui/browseui.h +++ b/dlls/browseui/browseui.h @@ -22,7 +22,9 @@ #define __WINE_BROWSEUI_H extern LONG BROWSEUI_refCount; +extern HINSTANCE BROWSEUI_hinstance; HRESULT WINAPI ACLMulti_Constructor(IUnknown *punkOuter, IUnknown **ppOut); +HRESULT WINAPI ProgressDialog_Constructor(IUnknown *punkOuter, IUnknown **ppOut); #endif /* __WINE_SHDOCVW_H */ diff --git a/dlls/browseui/browseui_main.c b/dlls/browseui/browseui_main.c index 98b1424390e..8e93cf3b062 100644 --- a/dlls/browseui/browseui_main.c +++ b/dlls/browseui/browseui_main.c @@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(browseui); LONG BROWSEUI_refCount = 0; -HINSTANCE browseui_hinstance = 0; +HINSTANCE BROWSEUI_hinstance = 0; typedef HRESULT (WINAPI *LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut); @@ -50,6 +50,7 @@ static const struct { LPFNCONSTRUCTOR ctor; } ClassesTable[] = { {&CLSID_ACLMulti, ACLMulti_Constructor}, + {&CLSID_ProgressDialog, ProgressDialog_Constructor}, {NULL, NULL} }; @@ -161,7 +162,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinst); - browseui_hinstance = hinst; + BROWSEUI_hinstance = hinst; break; } return TRUE; diff --git a/dlls/browseui/progressdlg.c b/dlls/browseui/progressdlg.c new file mode 100644 index 00000000000..697d1146e74 --- /dev/null +++ b/dlls/browseui/progressdlg.c @@ -0,0 +1,506 @@ +/* + * Progress dialog + * + * Copyright 2007 Mikolaj Zalewski + * + * 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 + */ + +#include "config.h" + +#include + +#define COBJMACROS + +#include "wine/debug.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winuser.h" +#include "shlwapi.h" +#include "winerror.h" +#include "objbase.h" + +#include "shlguid.h" +#include "shlobj.h" + +#include "wine/unicode.h" + +#include "browseui.h" +#include "resids.h" + +WINE_DEFAULT_DEBUG_CHANNEL(browseui); + +#define CANCEL_MSG_LINE 2 + +/* Note: to avoid a deadlock we don't want to send messages to the dialog + * with the critical section held. Instead we only mark what fields shoud be + * updated and the dialog proc does the update */ +#define UPDATE_PROGRESS 0x1 +#define UPDATE_TITLE 0x2 +#define UPDATE_LINE1 0x4 +#define UPDATE_LINE2 (UPDATE_LINE1<<1) +#define UPDATE_LINE3 (UPDATE_LINE2<<2) + + +#define WM_DLG_UPDATE (WM_APP+1) /* set to the dialog when it should update */ +#define WM_DLG_DESTROY (WM_APP+2) /* DestroyWindow must be called from the owning thread */ + +typedef struct tagProgressDialog { + const IProgressDialogVtbl *vtbl; + LONG refCount; + CRITICAL_SECTION cs; + HWND hwnd; + DWORD dwFlags; + DWORD dwUpdate; + LPWSTR lines[3]; + LPWSTR cancelMsg; + LPWSTR title; + BOOL isCancelled; + ULONGLONG ullCompleted; + ULONGLONG ullTotal; + HWND hwndDisabledParent; /* For modal dialog: the parent that need to be re-enabled when the dialog ends */ +} ProgressDialog; + +static const IProgressDialogVtbl ProgressDialogVtbl; + +static void set_buffer(LPWSTR *buffer, LPCWSTR string) +{ + const WCHAR empty_string = {0}; + IMalloc *malloc; + int cb; + + if (string == NULL) + string = empty_string; + CoGetMalloc(1, &malloc); + + cb = (strlenW(string) + 1)*sizeof(WCHAR); + if (*buffer == NULL || cb > IMalloc_GetSize(malloc, *buffer)) + *buffer = IMalloc_Realloc(malloc, *buffer, cb); + memcpy(*buffer, string, cb); +} + +struct create_params +{ + ProgressDialog *This; + HANDLE hEvent; + HWND hwndParent; +}; + +static LPWSTR load_string(HINSTANCE hInstance, UINT uiResourceId) +{ + WCHAR string[256]; + LPWSTR ret; + + LoadStringW(hInstance, uiResourceId, string, sizeof(string)/sizeof(string[0])); + ret = HeapAlloc(GetProcessHeap(), 0, (strlenW(string) + 1) * sizeof(WCHAR)); + strcpyW(ret, string); + return ret; +} + +static void set_progress_marquee(ProgressDialog *This) +{ + HWND hProgress = GetDlgItem(This->hwnd, IDC_PROGRESS_BAR); + SetWindowLongW(hProgress, GWL_STYLE, + GetWindowLongW(hProgress, GWL_STYLE)|PBS_MARQUEE); +} + +void update_dialog(ProgressDialog *This, DWORD dwUpdate) +{ + WCHAR empty[] = {0}; + + if (dwUpdate & UPDATE_TITLE) + SetWindowTextW(This->hwnd, This->title); + + if (dwUpdate & UPDATE_LINE1) + SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE, (This->isCancelled ? empty : This->lines[0])); + if (dwUpdate & UPDATE_LINE2) + SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE+1, (This->isCancelled ? empty : This->lines[1])); + if (dwUpdate & UPDATE_LINE3) + SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE+2, (This->isCancelled ? This->cancelMsg : This->lines[2])); + + if (dwUpdate & UPDATE_PROGRESS) + { + ULONGLONG ullTotal = This->ullTotal; + ULONGLONG ullCompleted = This->ullCompleted; + + /* progress bar requires 32-bit coordinates */ + while (ullTotal >> 32) + { + ullTotal >>= 1; + ullCompleted >>= 1; + } + + SendDlgItemMessageW(This->hwnd, IDC_PROGRESS_BAR, PBM_SETRANGE32, 0, (DWORD)ullTotal); + SendDlgItemMessageW(This->hwnd, IDC_PROGRESS_BAR, PBM_SETPOS, (DWORD)ullCompleted, 0); + } +} + +static void end_dialog(ProgressDialog *This) +{ + SendMessageW(This->hwnd, WM_DLG_DESTROY, 0, 0); + /* native doesn't reenable the window? */ + if (This->hwndDisabledParent) + EnableWindow(This->hwndDisabledParent, TRUE); + This->hwnd = NULL; +} + +static INT_PTR CALLBACK dialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ProgressDialog *This = (ProgressDialog *)GetWindowLongPtrW(hwnd, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + struct create_params *params = (struct create_params *)lParam; + + /* Note: until we set the hEvent, the object is protected by + * the critical section held by StartProgress */ + SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params->This); + This = params->This; + This->hwnd = hwnd; + + if (This->dwFlags & PROGDLG_NOPROGRESSBAR) + ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS_BAR), SW_HIDE); + if (This->dwFlags & PROGDLG_NOCANCEL) + ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE); + if (This->dwFlags & PROGDLG_MARQUEEPROGRESS) + set_progress_marquee(This); + + update_dialog(This, 0xffffffff); + This->dwUpdate = 0; + This->isCancelled = FALSE; + SetEvent(params->hEvent); + return TRUE; + } + + case WM_DLG_UPDATE: + EnterCriticalSection(&This->cs); + update_dialog(This, This->dwUpdate); + This->dwUpdate = 0; + LeaveCriticalSection(&This->cs); + return TRUE; + + case WM_DLG_DESTROY: + DestroyWindow(hwnd); + PostThreadMessageW(GetCurrentThreadId(), WM_NULL, 0, 0); /* wake up the GetMessage */ + return TRUE; + + case WM_CLOSE: + case WM_COMMAND: + if (msg == WM_CLOSE || wParam == IDCANCEL) + { + EnterCriticalSection(&This->cs); + This->isCancelled = TRUE; + + if (!This->cancelMsg) + This->cancelMsg = load_string(BROWSEUI_hinstance, IDS_CANCELLING); + + set_progress_marquee(This); + EnableWindow(GetDlgItem(This->hwnd, IDCANCEL), FALSE); + update_dialog(This, UPDATE_LINE1|UPDATE_LINE2|UPDATE_LINE3); + LeaveCriticalSection(&This->cs); + } + return TRUE; + } + return FALSE; +} + +static DWORD WINAPI dialog_thread(LPVOID lpParameter) +{ + /* Note: until we set the hEvent in WM_INITDIALOG, the ProgressDialog object + * is protected by the critical section held by StartProgress */ + struct create_params *params = (struct create_params *)lpParameter; + HWND hwnd; + MSG msg; + + hwnd = CreateDialogParamW(BROWSEUI_hinstance, MAKEINTRESOURCEW(IDD_PROGRESS_DLG), + params->hwndParent, dialog_proc, (LPARAM)params); + + while (GetMessageW(&msg, NULL, 0, 0) > 0) + { + if (!IsWindow(hwnd)) + break; + if(!IsDialogMessageW(hwnd, &msg)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + return 0; +} + +HRESULT WINAPI ProgressDialog_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) +{ + ProgressDialog *This; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + This = CoTaskMemAlloc(sizeof(ProgressDialog)); + if (This == NULL) + return E_OUTOFMEMORY; + ZeroMemory(This, sizeof(*This)); + This->vtbl = &ProgressDialogVtbl; + This->refCount = 1; + InitializeCriticalSection(&This->cs); + + TRACE("returning %p\n", This); + *ppOut = (IUnknown *)This; + BROWSEUI_refCount++; + return S_OK; +} + +static void WINAPI ProgressDialog_Destructor(ProgressDialog *This) +{ + TRACE("destroying %p\n", This); + if (This->hwnd) + end_dialog(This); + CoTaskMemFree(This->lines[0]); + CoTaskMemFree(This->lines[1]); + CoTaskMemFree(This->lines[2]); + CoTaskMemFree(This->cancelMsg); + CoTaskMemFree(This->title); + CoTaskMemFree(This); + BROWSEUI_refCount--; +} + +static HRESULT WINAPI ProgressDialog_QueryInterface(IProgressDialog *iface, REFIID iid, LPVOID *ppvOut) +{ + ProgressDialog *This = (ProgressDialog *)iface; + *ppvOut = NULL; + + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IProgressDialog)) + { + *ppvOut = This; + } + + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } + + WARN("unsupported interface: %s\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ProgressDialog_AddRef(IProgressDialog *iface) +{ + ProgressDialog *This = (ProgressDialog *)iface; + return InterlockedIncrement(&This->refCount); +} + +static ULONG WINAPI ProgressDialog_Release(IProgressDialog *iface) +{ + ProgressDialog *This = (ProgressDialog *)iface; + ULONG ret; + + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + ProgressDialog_Destructor(This); + return ret; +} + +static HRESULT WINAPI ProgressDialog_StartProgressDialog(IProgressDialog *iface, HWND hwndParent, IUnknown *punkEnableModeless, DWORD dwFlags, LPCVOID reserved) +{ + ProgressDialog *This = (ProgressDialog *)iface; + struct create_params params; + HANDLE hThread; + + TRACE("(%p, %p, %x, %p)\n", iface, punkEnableModeless, dwFlags, reserved); + if (punkEnableModeless || reserved) + FIXME("Reserved parameters not null (%p, %p)\n", punkEnableModeless, reserved); + if (dwFlags & PROGDLG_AUTOTIME) + FIXME("Flags PROGDLG_AUTOTIME not supported\n"); + if (dwFlags & PROGDLG_NOTIME) + FIXME("Flags PROGDLG_NOTIME not supported\n"); + if (dwFlags & PROGDLG_NOMINIMIZE) + FIXME("Flags PROGDLG_NOMINIMIZE not supported\n"); + + EnterCriticalSection(&This->cs); + + if (This->hwnd) + { + LeaveCriticalSection(&This->cs); + return S_OK; /* as on XP */ + } + This->dwFlags = dwFlags; + params.This = This; + params.hwndParent = hwndParent; + params.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + + hThread = CreateThread(NULL, 0, dialog_thread, ¶ms, 0, NULL); + WaitForSingleObject(params.hEvent, INFINITE); + + This->hwndDisabledParent = NULL; + if (hwndParent && (dwFlags & PROGDLG_MODAL)) + { + HWND hwndDisable = GetAncestor(hwndParent, GA_ROOT); + if (EnableWindow(hwndDisable, FALSE)) + This->hwndDisabledParent = hwndDisable; + } + + LeaveCriticalSection(&This->cs); + + return S_OK; +} + +static HRESULT WINAPI ProgressDialog_StopProgressDialog(IProgressDialog *iface) +{ + ProgressDialog *This = (ProgressDialog *)iface; + + EnterCriticalSection(&This->cs); + if (This->hwnd) + end_dialog(This); + LeaveCriticalSection(&This->cs); + + return S_OK; +} + +static HRESULT WINAPI ProgressDialog_SetTitle(IProgressDialog *iface, LPCWSTR pwzTitle) +{ + ProgressDialog *This = (ProgressDialog *)iface; + HWND hwnd; + + TRACE("(%p, %s)\n", This, wine_dbgstr_w(pwzTitle)); + + EnterCriticalSection(&This->cs); + set_buffer(&This->title, pwzTitle); + This->dwUpdate |= UPDATE_TITLE; + hwnd = This->hwnd; + LeaveCriticalSection(&This->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +static HRESULT WINAPI ProgressDialog_SetAnimation(IProgressDialog *iface, HINSTANCE hInstance, UINT uiResourceId) +{ + FIXME("(%p, %p, %d) - stub\n", iface, hInstance, uiResourceId); + return S_OK; +} + +static BOOL WINAPI ProgressDialog_HasUserCancelled(IProgressDialog *iface) +{ + ProgressDialog *This = (ProgressDialog *)iface; + return This->isCancelled; +} + +static HRESULT WINAPI ProgressDialog_SetProgress64(IProgressDialog *iface, ULONGLONG ullCompleted, ULONGLONG ullTotal) +{ + ProgressDialog *This = (ProgressDialog *)iface; + HWND hwnd; + + TRACE("(%p, %llu, %llu)\n", This, ullCompleted, ullTotal); + + EnterCriticalSection(&This->cs); + This->ullTotal = ullTotal; + This->ullCompleted = ullCompleted; + This->dwUpdate |= UPDATE_PROGRESS; + hwnd = This->hwnd; + LeaveCriticalSection(&This->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; /* Windows sometimes returns S_FALSE */ +} + +static HRESULT WINAPI ProgressDialog_SetProgress(IProgressDialog *iface, DWORD dwCompleted, DWORD dwTotal) +{ + return IProgressDialog_SetProgress64(iface, dwCompleted, dwTotal); +} + +static HRESULT WINAPI ProgressDialog_SetLine(IProgressDialog *iface, DWORD dwLineNum, LPCWSTR pwzLine, BOOL bPath, LPCVOID reserved) +{ + ProgressDialog *This = (ProgressDialog *)iface; + HWND hwnd; + + TRACE("(%p, %d, %s, %d)\n", This, dwLineNum, wine_dbgstr_w(pwzLine), bPath); + + if (reserved) + FIXME("reserved pointer not null (%p)\n", reserved); + + dwLineNum--; + if (dwLineNum >= 3) /* Windows seems to do something like that */ + dwLineNum = 0; + + EnterCriticalSection(&This->cs); + set_buffer(&This->lines[dwLineNum], pwzLine); + This->dwUpdate |= UPDATE_LINE1 << dwLineNum; + hwnd = (This->isCancelled ? NULL : This->hwnd); /* no sense to send the message if window cancelled */ + LeaveCriticalSection(&This->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +static HRESULT WINAPI ProgressDialog_SetCancelMsg(IProgressDialog *iface, LPCWSTR pwzMsg, LPCVOID reserved) +{ + ProgressDialog *This = (ProgressDialog *)iface; + HWND hwnd; + + TRACE("(%p, %s)\n", This, wine_dbgstr_w(pwzMsg)); + + if (reserved) + FIXME("reserved pointer not null (%p)\n", reserved); + + EnterCriticalSection(&This->cs); + set_buffer(&This->cancelMsg, pwzMsg); + This->dwUpdate |= UPDATE_LINE1 << CANCEL_MSG_LINE; + hwnd = (This->isCancelled ? This->hwnd : NULL); /* no sense to send the message if window not cancelled */ + LeaveCriticalSection(&This->cs); + + if (hwnd) + SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0); + + return S_OK; +} + +static HRESULT WINAPI ProgressDialog_Timer(IProgressDialog *iface, DWORD dwTimerAction, LPCVOID reserved) +{ + ProgressDialog *This = (ProgressDialog *)iface; + + FIXME("(%p, %d, %p) - stub\n", This, dwTimerAction, reserved); + + if (reserved) + FIXME("Reserved field not NULL but %p\n", reserved); + + return S_OK; +} + +static const IProgressDialogVtbl ProgressDialogVtbl = +{ + ProgressDialog_QueryInterface, + ProgressDialog_AddRef, + ProgressDialog_Release, + + ProgressDialog_StartProgressDialog, + ProgressDialog_StopProgressDialog, + ProgressDialog_SetTitle, + ProgressDialog_SetAnimation, + ProgressDialog_HasUserCancelled, + ProgressDialog_SetProgress, + ProgressDialog_SetProgress64, + ProgressDialog_SetLine, + ProgressDialog_SetCancelMsg, + ProgressDialog_Timer +}; diff --git a/dlls/browseui/regsvr.c b/dlls/browseui/regsvr.c index 889acdefc32..5019f213d2a 100644 --- a/dlls/browseui/regsvr.c +++ b/dlls/browseui/regsvr.c @@ -447,6 +447,13 @@ static struct regsvr_coclass const coclass_list[] = { "browseui.dll", "Apartment" }, + { + &CLSID_ProgressDialog, + "Progress Dialog", + NULL, + "browseui.dll", + "Both" + }, { NULL } /* list terminator */ }; diff --git a/dlls/browseui/browseui.h b/dlls/browseui/resids.h similarity index 77% copy from dlls/browseui/browseui.h copy to dlls/browseui/resids.h index 2f44ac74914..a5b53371580 100644 --- a/dlls/browseui/browseui.h +++ b/dlls/browseui/resids.h @@ -1,6 +1,4 @@ /* - * Internal header for browseui.dll - * * Copyright 2007 Mikolaj Zalewski * * This library is free software; you can redistribute it and/or @@ -18,11 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __WINE_BROWSEUI_H -#define __WINE_BROWSEUI_H - -extern LONG BROWSEUI_refCount; +#define IDS_CANCELLING 16 -HRESULT WINAPI ACLMulti_Constructor(IUnknown *punkOuter, IUnknown **ppOut); +#define IDC_ANIMATION 100 +#define IDC_PROGRESS_BAR 102 +#define IDC_TEXT_LINE 103 -#endif /* __WINE_SHDOCVW_H */ +#define IDD_PROGRESS_DLG 100 diff --git a/dlls/browseui/browseui.h b/dlls/browseui/rsrc.rc similarity index 77% copy from dlls/browseui/browseui.h copy to dlls/browseui/rsrc.rc index 2f44ac74914..c4557dfad74 100644 --- a/dlls/browseui/browseui.h +++ b/dlls/browseui/rsrc.rc @@ -1,6 +1,4 @@ /* - * Internal header for browseui.dll - * * Copyright 2007 Mikolaj Zalewski * * This library is free software; you can redistribute it and/or @@ -18,11 +16,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __WINE_BROWSEUI_H -#define __WINE_BROWSEUI_H +#include "windef.h" +#include "winuser.h" +#include "commctrl.h" -extern LONG BROWSEUI_refCount; +#include "resids.h" -HRESULT WINAPI ACLMulti_Constructor(IUnknown *punkOuter, IUnknown **ppOut); +#include "version.rc" -#endif /* __WINE_SHDOCVW_H */ +#include "rsrc_En.rc" diff --git a/dlls/browseui/browseui.h b/dlls/browseui/rsrc_En.rc similarity index 52% copy from dlls/browseui/browseui.h copy to dlls/browseui/rsrc_En.rc index 2f44ac74914..1749d1cb6ff 100644 --- a/dlls/browseui/browseui.h +++ b/dlls/browseui/rsrc_En.rc @@ -1,6 +1,4 @@ /* - * Internal header for browseui.dll - * * Copyright 2007 Mikolaj Zalewski * * This library is free software; you can redistribute it and/or @@ -18,11 +16,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __WINE_BROWSEUI_H -#define __WINE_BROWSEUI_H -extern LONG BROWSEUI_refCount; +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT -HRESULT WINAPI ACLMulti_Constructor(IUnknown *punkOuter, IUnknown **ppOut); +STRINGTABLE +{ + IDS_CANCELLING "Cancelling..." +} -#endif /* __WINE_SHDOCVW_H */ +IDD_PROGRESS_DLG DIALOG 0, 0, 260, 85 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", IDC_ANIMATION, ANIMATE_CLASSA, 0, 12, 10, 236, 25 /* TODO: style */ + LTEXT "", IDC_TEXT_LINE, 7, 45, 250, 10, SS_LEFT|SS_NOPREFIX + LTEXT "", IDC_TEXT_LINE + 1, 7, 55, 250, 10, SS_LEFT|SS_NOPREFIX + CONTROL "", IDC_PROGRESS_BAR, PROGRESS_CLASSA, WS_BORDER, 7, 65, 190, 8 + PUSHBUTTON "&Cancel", IDCANCEL, 205, 65, 40, 15, WS_GROUP | WS_TABSTOP | WS_VISIBLE + LTEXT "", IDC_TEXT_LINE + 2, 7, 75, 190, 10, SS_LEFT|SS_NOPREFIX +} diff --git a/dlls/credui/credui.spec b/dlls/credui/credui.spec index 20146c7791a..974849bcecb 100644 --- a/dlls/credui/credui.spec +++ b/dlls/credui/credui.spec @@ -7,10 +7,10 @@ @ stdcall CredUIParseUserNameW(wstr ptr long ptr long) @ stub CredUIPromptForCredentialsA @ stdcall CredUIPromptForCredentialsW(ptr wstr ptr long ptr long ptr long ptr long) -@ stub CredUIReadSSOCredA -@ stub CredUIReadSSOCredW -@ stub CredUIStoreSSOCredA -@ stub CredUIStoreSSOCredW +@ stdcall CredUIReadSSOCredA(str ptr) +@ stdcall CredUIReadSSOCredW(wstr ptr) +@ stdcall CredUIStoreSSOCredA(str str str long) +@ stdcall CredUIStoreSSOCredW(wstr wstr wstr long) @ stub DllCanUnloadNow @ stub DllGetClassObject @ stub DllRegisterServer diff --git a/dlls/credui/credui_main.c b/dlls/credui/credui_main.c index fc7bfe04fd2..dfaa06eaa98 100644 --- a/dlls/credui/credui_main.c +++ b/dlls/credui/credui_main.c @@ -249,3 +249,43 @@ DWORD WINAPI CredUIParseUserNameW(PCWSTR pszUserName, PWSTR pszUser, return ERROR_SUCCESS; } + +/****************************************************************************** + * CredUIStoreSSOCredA [CREDUI.@] + */ +DWORD WINAPI CredUIStoreSSOCredA(PCSTR a, PCSTR b, PCSTR c, BOOL f) +{ + FIXME("(%s, %s, %s, %d)\n", debugstr_a(a), debugstr_a(b), debugstr_a(c), f); + return 0; +} + +/****************************************************************************** + * CredUIStoreSSOCredW [CREDUI.@] + */ +DWORD WINAPI CredUIStoreSSOCredW(PCWSTR a, PCWSTR b, PCWSTR c, BOOL f) +{ + FIXME("(%s, %s, %s, %d)\n", debugstr_w(a), debugstr_w(b), debugstr_w(c), f); + return 0; +} + +/****************************************************************************** + * CredUIReadSSOCredA [CREDUI.@] + */ +DWORD WINAPI CredUIReadSSOCredA(PCSTR a, PSTR *b) +{ + FIXME("(%s, %p)\n", debugstr_a(a), b); + if (b) + *b = NULL; + return 0; +} + +/****************************************************************************** + * CredUIReadSSOCredW [CREDUI.@] + */ +DWORD WINAPI CredUIReadSSOCredW(PCWSTR a, PWSTR *b) +{ + FIXME("(%s, %p)\n", debugstr_w(a), b); + if (b) + *b = NULL; + return 0; +} diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index d356c405037..976589b7edc 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1231,6 +1231,88 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, return ret; } +typedef struct _OLD_CERT_REVOCATION_STATUS { + DWORD cbSize; + DWORD dwIndex; + DWORD dwError; + DWORD dwReason; +} OLD_CERT_REVOCATION_STATUS, *POLD_CERT_REVOCATION_STATUS; + +typedef BOOL (WINAPI *CertVerifyRevocationFunc)(DWORD, DWORD, DWORD, + void **, DWORD, PCERT_REVOCATION_PARA, PCERT_REVOCATION_STATUS); + +BOOL WINAPI CertVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, + DWORD cContext, void *rgpvContext[], DWORD dwFlags, + PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus) +{ + BOOL ret; + + TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType, + cContext, rgpvContext, dwFlags, pRevPara, pRevStatus); + + if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) && + pRevStatus->cbSize != sizeof(CERT_REVOCATION_STATUS)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + if (cContext) + { + static HCRYPTOIDFUNCSET set = NULL; + DWORD size; + + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_VERIFY_REVOCATION_FUNC, 0); + ret = CryptGetDefaultOIDDllList(set, dwEncodingType, NULL, &size); + if (ret) + { + if (size == 1) + { + /* empty list */ + SetLastError(CRYPT_E_NO_REVOCATION_DLL); + ret = FALSE; + } + else + { + LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR)), ptr; + + if (dllList) + { + ret = CryptGetDefaultOIDDllList(set, dwEncodingType, + dllList, &size); + if (ret) + { + for (ptr = dllList; ret && *ptr; + ptr += lstrlenW(ptr) + 1) + { + CertVerifyRevocationFunc func; + HCRYPTOIDFUNCADDR hFunc; + + ret = CryptGetDefaultOIDFunctionAddress(set, + dwEncodingType, ptr, 0, (void **)&func, &hFunc); + if (ret) + { + ret = func(dwEncodingType, dwRevType, cContext, + rgpvContext, dwFlags, pRevPara, pRevStatus); + CryptFreeOIDFunctionAddress(hFunc, 0); + } + } + } + CryptMemFree(dllList); + } + else + { + SetLastError(ERROR_OUTOFMEMORY); + ret = FALSE; + } + } + } + } + else + ret = TRUE; + return ret; +} + PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, CRYPT_ATTRIBUTE rgAttr[]) { diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index 92043b127ec..068e039dd62 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -20,6 +20,8 @@ #define NONAMELESSUNION #include "windef.h" #include "winbase.h" +#define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS +#define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS #include "wincrypt.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -775,7 +777,6 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER; CRYPT_CheckRootCert(engine->hRoot, rootElement); } - /* FIXME: check revocation of every cert with CertVerifyRevocation */ CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus); } @@ -1307,19 +1308,123 @@ static BOOL CRYPT_AddAlternateChainToChain(PCertificateChain chain, return ret; } +static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain( + PCERT_CHAIN_CONTEXT chain, DWORD i) +{ + DWORD j, iElement; + PCERT_CHAIN_ELEMENT element = NULL; + + for (j = 0, iElement = 0; !element && j < chain->cChain; j++) + { + if (iElement + chain->rgpChain[j]->cElement < i) + iElement += chain->rgpChain[j]->cElement; + else + element = chain->rgpChain[j]->rgpElement[i - iElement]; + } + return element; +} + typedef struct _CERT_CHAIN_PARA_NO_EXTRA_FIELDS { DWORD cbSize; CERT_USAGE_MATCH RequestedUsage; } CERT_CHAIN_PARA_NO_EXTRA_FIELDS, *PCERT_CHAIN_PARA_NO_EXTRA_FIELDS; -typedef struct _CERT_CHAIN_PARA_EXTRA_FIELDS { - DWORD cbSize; - CERT_USAGE_MATCH RequestedUsage; - CERT_USAGE_MATCH RequestedIssuancePolicy; - DWORD dwUrlRetrievalTimeout; - BOOL fCheckRevocationFreshnessTime; - DWORD dwRevocationFreshnessTime; -} CERT_CHAIN_PARA_EXTRA_FIELDS, *PCERT_CHAIN_PARA_EXTRA_FIELDS; +static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain, + LPFILETIME pTime, PCERT_CHAIN_PARA pChainPara, DWORD chainFlags) +{ + DWORD cContext; + + if (chainFlags & CERT_CHAIN_REVOCATION_CHECK_END_CERT) + cContext = 1; + else if ((chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN) || + (chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)) + { + DWORD i; + + for (i = 0, cContext = 0; i < chain->cChain; i++) + { + if (i < chain->cChain - 1 || + chainFlags & CERT_CHAIN_REVOCATION_CHECK_CHAIN) + cContext += chain->rgpChain[i]->cElement; + else + cContext += chain->rgpChain[i]->cElement - 1; + } + } + else + cContext = 0; + if (cContext) + { + PCCERT_CONTEXT *contexts = + CryptMemAlloc(cContext * sizeof(PCCERT_CONTEXT *)); + + if (contexts) + { + DWORD i, j, iContext, revocationFlags; + CERT_REVOCATION_PARA revocationPara = { sizeof(revocationPara), 0 }; + CERT_REVOCATION_STATUS revocationStatus = + { sizeof(revocationStatus), 0 }; + BOOL ret; + + for (i = 0, iContext = 0; iContext < cContext && i < chain->cChain; + i++) + { + for (j = 0; iContext < cContext && + j < chain->rgpChain[i]->cElement; j++) + contexts[iContext++] = + chain->rgpChain[i]->rgpElement[j]->pCertContext; + } + revocationFlags = CERT_VERIFY_REV_CHAIN_FLAG; + if (chainFlags & CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY) + revocationFlags |= CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION; + if (chainFlags & CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT) + revocationFlags |= CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG; + revocationPara.pftTimeToUse = pTime; + if (pChainPara->cbSize == sizeof(CERT_CHAIN_PARA)) + { + revocationPara.dwUrlRetrievalTimeout = + pChainPara->dwUrlRetrievalTimeout; + revocationPara.fCheckFreshnessTime = + pChainPara->fCheckRevocationFreshnessTime; + revocationPara.dwFreshnessTime = + pChainPara->dwRevocationFreshnessTime; + } + ret = CertVerifyRevocation(X509_ASN_ENCODING, + CERT_CONTEXT_REVOCATION_TYPE, cContext, (void **)contexts, + revocationFlags, &revocationPara, &revocationStatus); + if (!ret) + { + PCERT_CHAIN_ELEMENT element = + CRYPT_FindIthElementInChain(chain, revocationStatus.dwIndex); + DWORD error; + + switch (revocationStatus.dwError) + { + case CRYPT_E_NO_REVOCATION_CHECK: + case CRYPT_E_NO_REVOCATION_DLL: + case CRYPT_E_NOT_IN_REVOCATION_DATABASE: + error = CERT_TRUST_REVOCATION_STATUS_UNKNOWN; + break; + case CRYPT_E_REVOCATION_OFFLINE: + error = CERT_TRUST_IS_OFFLINE_REVOCATION; + break; + case CRYPT_E_REVOKED: + error = CERT_TRUST_IS_REVOKED; + break; + default: + WARN("unmapped error %08x\n", revocationStatus.dwError); + error = 0; + } + if (element) + { + /* FIXME: set element's pRevocationInfo member */ + element->TrustStatus.dwErrorStatus |= error; + } + chain->TrustStatus.dwErrorStatus |= error; + } + CryptMemFree(contexts); + } + } +} BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, @@ -1344,15 +1449,21 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, SetLastError(ERROR_INVALID_DATA); return FALSE; } + if (pChainPara->cbSize != sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS) && + pChainPara->cbSize != sizeof(CERT_CHAIN_PARA)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } if (!hChainEngine) hChainEngine = CRYPT_GetDefaultChainEngine(); /* FIXME: what about HCCE_LOCAL_MACHINE? */ - /* FIXME: pChainPara is for now ignored */ ret = CRYPT_BuildCandidateChainFromCert(hChainEngine, pCertContext, pTime, hAdditionalStore, &chain); if (ret) { PCertificateChain alternate = NULL; + PCERT_CHAIN_CONTEXT pChain; do { alternate = CRYPT_BuildAlternateContextFromChain(hChainEngine, @@ -1368,10 +1479,12 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, chain = CRYPT_ChooseHighestQualityChain(chain); if (!(dwFlags & CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS)) CRYPT_FreeLowerQualityChains(chain); + pChain = (PCERT_CHAIN_CONTEXT)chain; + CRYPT_VerifyChainRevocation(pChain, pTime, pChainPara, dwFlags); if (ppChainContext) - *ppChainContext = (PCCERT_CHAIN_CONTEXT)chain; + *ppChainContext = pChain; else - CertFreeCertificateChain((PCCERT_CHAIN_CONTEXT)chain); + CertFreeCertificateChain(pChain); } TRACE("returning %d\n", ret); return ret; diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 874d26d7c13..870ee482f95 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -90,7 +90,7 @@ @ stdcall CertVerifyCRLRevocation(long ptr long ptr) @ stdcall CertVerifyCRLTimeValidity(ptr ptr) @ stub CertVerifyCTLUsage -@ stub CertVerifyRevocation +@ stdcall CertVerifyRevocation(long long long ptr long ptr ptr) @ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr) @ stdcall CertVerifyTimeValidity(ptr ptr) @ stdcall CertVerifyValidityNesting(ptr ptr) diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 34c313f8dec..3c6aaa4179d 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -2575,6 +2575,39 @@ static void testVerifySubjectCert(void) CertFreeCertificateContext(context1); } +static void testVerifyRevocation(void) +{ + BOOL ret; + CERT_REVOCATION_STATUS status = { 0 }; + PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING, + bigCert, sizeof(bigCert)); + + /* Crash + ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL); + */ + SetLastError(0xdeadbeef); + ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + status.cbSize = sizeof(status); + ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); + ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); + ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status); + ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); + ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status); + ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status); + ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, + "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status); + ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, + "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); + + CertFreeCertificateContext(cert); +} + static BYTE privKey[] = { 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10, @@ -2921,6 +2954,7 @@ START_TEST(cert) testHashPublicKeyInfo(); testCompareCert(); testVerifySubjectCert(); + testVerifyRevocation(); testAcquireCertPrivateKey(); testGetPublicKeyLength(); } diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c index 603185df84b..d280ca4879a 100644 --- a/dlls/cryptnet/cryptnet_main.c +++ b/dlls/cryptnet/cryptnet_main.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Maarten Lankhorst + * Copyright 2007 Juan Lang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,8 +38,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); switch (fdwReason) { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; @@ -396,7 +395,6 @@ static BOOL CRYPT_GetObjectFromFile(HANDLE hFile, PCRYPT_BLOB_ARRAY pObject) } /* FIXME: should make wininet cache all downloads instead */ -/* FIXME: how do I know the cached object is up to date? */ static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject, PCRYPT_RETRIEVE_AUX_INFO pAuxInfo) { @@ -610,7 +608,7 @@ static BOOL CRYPT_DownloadObject(DWORD dwRetrievalFlags, HINTERNET hHttp, } static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject, - DWORD dwRetrievalFlags) + DWORD dwRetrievalFlags, FILETIME expires) { WCHAR cacheFileName[MAX_PATH]; @@ -633,7 +631,7 @@ static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject, WriteFile(hCacheFile, pObject->rgBlob[0].pbData, pObject->rgBlob[0].cbData, &bytesWritten, NULL); CloseHandle(hCacheFile); - CommitUrlCacheEntryW(pszURL, cacheFileName, ft, ft, entryType, + CommitUrlCacheEntryW(pszURL, cacheFileName, expires, ft, entryType, NULL, 0, NULL, NULL); } } @@ -785,6 +783,14 @@ static BOOL WINAPI HTTP_RetrieveEncodedObjectW(LPCWSTR pszURL, if (hHttp) { + if (dwTimeout) + { + InternetSetOptionW(hHttp, + INTERNET_OPTION_RECEIVE_TIMEOUT, &dwTimeout, + sizeof(dwTimeout)); + InternetSetOptionW(hHttp, INTERNET_OPTION_SEND_TIMEOUT, + &dwTimeout, sizeof(dwTimeout)); + } ret = HttpSendRequestExW(hHttp, NULL, NULL, 0, (DWORD_PTR)context); if (!ret && GetLastError() == ERROR_IO_PENDING) @@ -795,20 +801,38 @@ static BOOL WINAPI HTTP_RetrieveEncodedObjectW(LPCWSTR pszURL, else ret = TRUE; } - ret = HttpEndRequestW(hHttp, NULL, 0, (DWORD_PTR)context); - if (!ret && GetLastError() == ERROR_IO_PENDING) + /* We don't set ret to TRUE in this block to avoid masking + * an error from HttpSendRequestExW. + */ + if (!HttpEndRequestW(hHttp, NULL, 0, (DWORD_PTR)context) && + GetLastError() == ERROR_IO_PENDING) { if (WaitForSingleObject(context->event, context->timeout) == WAIT_TIMEOUT) + { SetLastError(ERROR_TIMEOUT); - else - ret = TRUE; + ret = FALSE; + } } if (ret) ret = CRYPT_DownloadObject(dwRetrievalFlags, hHttp, context, pObject, pAuxInfo); if (ret && !(dwRetrievalFlags & CRYPT_DONT_CACHE_RESULT)) - CRYPT_CacheURL(pszURL, pObject, dwRetrievalFlags); + { + SYSTEMTIME st; + DWORD len = sizeof(st); + + if (HttpQueryInfoW(hHttp, + HTTP_QUERY_EXPIRES | HTTP_QUERY_FLAG_SYSTEMTIME, &st, + &len, NULL)) + { + FILETIME ft; + + SystemTimeToFileTime(&st, &ft); + CRYPT_CacheURL(pszURL, pObject, dwRetrievalFlags, + ft); + } + } InternetCloseHandle(hHttp); } InternetCloseHandle(hHost); @@ -1301,6 +1325,13 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, return ret; } +typedef struct _OLD_CERT_REVOCATION_STATUS { + DWORD cbSize; + DWORD dwIndex; + DWORD dwError; + DWORD dwReason; +} OLD_CERT_REVOCATION_STATUS, *POLD_CERT_REVOCATION_STATUS; + /*********************************************************************** * CertDllVerifyRevocation (CRYPTNET.@) */ @@ -1308,7 +1339,118 @@ BOOL WINAPI CertDllVerifyRevocation(DWORD dwEncodingType, DWORD dwRevType, DWORD cContext, PVOID rgpvContext[], DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, PCERT_REVOCATION_STATUS pRevStatus) { - FIXME("(%08x, %d, %d, %p, %08x, %p, %p): stub\n", dwEncodingType, dwRevType, - cContext, rgpvContext, dwFlags, pRevPara, pRevStatus); - return FALSE; + DWORD error = 0, i; + BOOL ret; + + TRACE("(%08x, %d, %d, %p, %08x, %p, %p)\n", dwEncodingType, dwRevType, + cContext, rgpvContext, dwFlags, pRevPara, pRevStatus); + + if (pRevStatus->cbSize != sizeof(OLD_CERT_REVOCATION_STATUS) && + pRevStatus->cbSize != sizeof(CERT_REVOCATION_STATUS)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + memset(&pRevStatus->dwIndex, 0, pRevStatus->cbSize - sizeof(DWORD)); + if (dwRevType != CERT_CONTEXT_REVOCATION_TYPE) + { + error = CRYPT_E_NO_REVOCATION_CHECK; + ret = FALSE; + } + else + { + ret = TRUE; + for (i = 0; ret && i < cContext; i++) + { + DWORD cbUrlArray; + + ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, + rgpvContext[i], 0, NULL, &cbUrlArray, NULL, NULL, NULL); + if (!ret && GetLastError() == CRYPT_E_NOT_FOUND) + { + error = CRYPT_E_NO_REVOCATION_CHECK; + pRevStatus->dwIndex = i; + } + else if (ret) + { + CRYPT_URL_ARRAY *urlArray = CryptMemAlloc(cbUrlArray); + + if (urlArray) + { + DWORD j, retrievalFlags = 0, startTime, endTime, timeout; + + ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, + rgpvContext[i], 0, urlArray, &cbUrlArray, NULL, NULL, + NULL); + if (dwFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION) + retrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL; + if (dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG && + pRevPara->cbSize >= offsetof(CERT_REVOCATION_PARA, + dwUrlRetrievalTimeout) + sizeof(DWORD)) + { + startTime = GetTickCount(); + endTime = startTime + pRevPara->dwUrlRetrievalTimeout; + timeout = pRevPara->dwUrlRetrievalTimeout; + } + else + endTime = timeout = 0; + for (j = 0; ret && j < urlArray->cUrl; j++) + { + PCCRL_CONTEXT crl; + + ret = CryptRetrieveObjectByUrlW(urlArray->rgwszUrl[j], + CONTEXT_OID_CRL, retrievalFlags, timeout, + (void **)&crl, NULL, NULL, NULL, NULL); + if (ret) + { + PCRL_ENTRY entry = NULL; + + CertFindCertificateInCRL( + (PCCERT_CONTEXT)rgpvContext[i], crl, 0, NULL, + &entry); + if (entry) + { + error = CRYPT_E_REVOKED; + pRevStatus->dwIndex = i; + ret = FALSE; + } + else if (timeout) + { + DWORD time = GetTickCount(); + + if ((int)(endTime - time) <= 0) + { + error = ERROR_TIMEOUT; + pRevStatus->dwIndex = i; + ret = FALSE; + } + else + timeout = endTime - time; + } + CertFreeCRLContext(crl); + } + else + error = CRYPT_E_REVOCATION_OFFLINE; + } + CryptMemFree(urlArray); + } + else + { + error = ERROR_OUTOFMEMORY; + pRevStatus->dwIndex = i; + ret = FALSE; + } + } + else + pRevStatus->dwIndex = i; + } + } + + if (!ret) + { + SetLastError(error); + pRevStatus->dwError = error; + } + TRACE("returning %d (%08x)\n", ret, error); + return ret; } diff --git a/dlls/d3dx8/tests/math.c b/dlls/d3dx8/tests/math.c index c5d731b1f4b..0e70183a3da 100644 --- a/dlls/d3dx8/tests/math.c +++ b/dlls/d3dx8/tests/math.c @@ -24,12 +24,174 @@ #define admitted_error 0.00001f +#define expect_color(expectedcolor,gotcolor) ok((fabs(expectedcolor.r-gotcolor.r)r = (pc1->r) + (pc2->r); + pout->g = (pc1->g) + (pc2->g); + pout->b = (pc1->b) + (pc2->b); + pout->a = (pc1->a) + (pc2->a); + return pout; +} + +static inline D3DXCOLOR* D3DXColorLerp(D3DXCOLOR *pout, CONST D3DXCOLOR *pc1, CONST D3DXCOLOR *pc2, FLOAT s) +{ + if ( !pout || !pc1 || !pc2 ) return NULL; + pout->r = (1-s) * (pc1->r) + s *(pc2->r); + pout->g = (1-s) * (pc1->g) + s *(pc2->g); + pout->b = (1-s) * (pc1->b) + s *(pc2->b); + pout->a = (1-s) * (pc1->a) + s *(pc2->a); + return pout; +} + +static inline D3DXCOLOR* D3DXColorModulate(D3DXCOLOR *pout, CONST D3DXCOLOR *pc1, CONST D3DXCOLOR *pc2) +{ + if ( !pout || !pc1 || !pc2 ) return NULL; + pout->r = (pc1->r) * (pc2->r); + pout->g = (pc1->g) * (pc2->g); + pout->b = (pc1->b) * (pc2->b); + pout->a = (pc1->a) * (pc2->a); + return pout; +} + +static inline D3DXCOLOR* D3DXColorNegative(D3DXCOLOR *pout, CONST D3DXCOLOR *pc) +{ + if ( !pout || !pc ) return NULL; + pout->r = 1.0f - pc->r; + pout->g = 1.0f - pc->g; + pout->b = 1.0f - pc->b; + pout->a = pc->a; + return pout; +} + +static inline D3DXCOLOR* D3DXColorScale(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s) +{ + if ( !pout || !pc ) return NULL; + pout->r = s* (pc->r); + pout->g = s* (pc->g); + pout->b = s* (pc->b); + pout->a = s* (pc->a); + return pout; +} + +static inline D3DXCOLOR* D3DXColorSubtract(D3DXCOLOR *pout, CONST D3DXCOLOR *pc1, CONST D3DXCOLOR *pc2) +{ + if ( !pout || !pc1 || !pc2 ) return NULL; + pout->r = (pc1->r) - (pc2->r); + pout->g = (pc1->g) - (pc2->g); + pout->b = (pc1->b) - (pc2->b); + pout->a = (pc1->a) - (pc2->a); + return pout; +} + /*_______________D3DXVECTOR2________________________*/ static inline D3DXVECTOR2* D3DXVec2Add(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2) @@ -256,6 +318,68 @@ static inline D3DXVECTOR4* D3DXVec4Subtract(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 return pout; } +/*__________________D3DXMatrix____________________*/ + +static inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX *pout) +{ + if ( !pout ) return NULL; + pout->m[0][1] = 0.0f; + pout->m[0][2] = 0.0f; + pout->m[0][3] = 0.0f; + pout->m[1][0] = 0.0f; + pout->m[1][2] = 0.0f; + pout->m[1][3] = 0.0f; + pout->m[2][0] = 0.0f; + pout->m[2][1] = 0.0f; + pout->m[2][3] = 0.0f; + pout->m[3][0] = 0.0f; + pout->m[3][1] = 0.0f; + pout->m[3][2] = 0.0f; + pout->m[0][0] = 1.0f; + pout->m[1][1] = 1.0f; + pout->m[2][2] = 1.0f; + pout->m[3][3] = 1.0f; + return pout; +} + +static inline BOOL D3DXMatrixIsIdentity(D3DXMATRIX *pm) +{ + int i,j; + D3DXMATRIX testmatrix; + BOOL equal=TRUE; + + if ( !pm ) return FALSE; + D3DXMatrixIdentity(&testmatrix); + for (i=0; i<4; i++) + { + for (j=0; j<4; j++) + { + if ( fabs(pm->m[i][j] - testmatrix.m[i][j]) > 0.0001 ) equal = FALSE; + } + } + return equal; +} + +/*__________________D3DXPLANE____________________*/ + +static inline FLOAT D3DXPlaneDot(CONST D3DXPLANE *pp, CONST D3DXVECTOR4 *pv) +{ + if ( !pp || !pv ) return 0.0f; + return ( (pp->a) * (pv->x) + (pp->b) * (pv->y) + (pp->c) * (pv->z) + (pp->d) * (pv->w) ); +} + +static inline FLOAT D3DXPlaneDotCoord(CONST D3DXPLANE *pp, CONST D3DXVECTOR4 *pv) +{ + if ( !pp || !pv ) return 0.0f; + return ( (pp->a) * (pv->x) + (pp->b) * (pv->y) + (pp->c) * (pv->z) + (pp->d) ); +} + +static inline FLOAT D3DXPlaneDotNormal(CONST D3DXPLANE *pp, CONST D3DXVECTOR4 *pv) +{ + if ( !pp || !pv ) return 0.0f; + return ( (pp->a) * (pv->x) + (pp->b) * (pv->y) + (pp->c) * (pv->z) ); +} + /*__________________D3DXQUATERNION____________________*/ static inline D3DXQUATERNION* D3DXQuaternionConjugate(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq) diff --git a/include/rpc.h b/include/rpc.h index c52e539267d..60bf4fe7adb 100644 --- a/include/rpc.h +++ b/include/rpc.h @@ -20,7 +20,11 @@ #ifndef RPC_NO_WINDOWS_H # ifdef __WINESRC__ +# ifndef RC_INVOKED +# include +# endif # include +# include # else # include # endif diff --git a/include/shlguid.h b/include/shlguid.h index be80199e466..503f4fc1e34 100644 --- a/include/shlguid.h +++ b/include/shlguid.h @@ -54,6 +54,9 @@ DEFINE_GUID(IID_IACList, 0x77A130B0L,0x94FD,0x11D0,0xA5,0x44,0x00,0xC0,0x4F,0x DEFINE_GUID(IID_IACList2, 0x470141A0L,0x5186,0x11D2,0xBB,0xB6,0x00,0x60,0x97,0x7B,0x46,0x4C); DEFINE_GUID(IID_IObjMgr, 0x00BB2761L,0x6A77,0x11D0,0xA5,0x35,0x00,0xC0,0x4F,0xD7,0xD0,0x62); +DEFINE_GUID(IID_IProgressDialog, 0xEBBC7C04,0x315E,0x11D2,0xB6,0x2F,0x00,0x60,0x97,0xDF,0x5B,0xD4); + + /* avoid duplicate definitions with shobjidl.h (FIXME) */ /* DEFINE_OLEGUID(IID_IShellPropSheetExt, 0x000214E9L, 0, 0); */ /* DEFINE_OLEGUID(IID_IExtractIconA, 0x000214EBL, 0, 0); */ @@ -122,8 +125,10 @@ DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00 DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); -DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); -DEFINE_GUID(CLSID_ACLMulti, 0x00bb2765, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); +DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); +DEFINE_GUID(CLSID_ACLMulti, 0x00bb2765, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); + +DEFINE_GUID(CLSID_ProgressDialog, 0xf8383852, 0xfcd3, 0x11d1, 0xa6, 0xb9, 0x0, 0x60, 0x97, 0xdf, 0x5b, 0xd4); #define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0} DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); diff --git a/include/shlobj.h b/include/shlobj.h index d93a69d112c..bd531c898fb 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -359,6 +359,59 @@ DECLARE_INTERFACE_(IACList,IUnknown) #define IACList_Expand(p,a) (p)->lpVtbl->Expand(p,a) #endif +/* IProgressDialog interface */ +#define PROGDLG_NORMAL 0x00000000 +#define PROGDLG_MODAL 0x00000001 +#define PROGDLG_AUTOTIME 0x00000002 +#define PROGDLG_NOTIME 0x00000004 +#define PROGDLG_NOMINIMIZE 0x00000008 +#define PROGDLG_NOPROGRESSBAR 0x00000010 +#define PROGDLG_MARQUEEPROGRESS 0x00000020 +#define PROGDLG_NOCANCEL 0x00000040 + +#define PDTIMER_RESET 0x00000001 +#define PDTIMER_PAUSE 0x00000002 +#define PDTIMER_RESUME 0x00000003 + +#define INTERFACE IProgressDialog +DECLARE_INTERFACE_(IProgressDialog,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IProgressDialog methods ***/ + STDMETHOD(StartProgressDialog)(THIS_ HWND hwndParent, IUnknown *punkEnableModeless, DWORD dwFlags, LPCVOID reserved) PURE; + STDMETHOD(StopProgressDialog)(THIS) PURE; + STDMETHOD(SetTitle)(THIS_ LPCWSTR pwzTitle) PURE; + STDMETHOD(SetAnimation)(THIS_ HINSTANCE hInstance, UINT uiResourceId) PURE; + STDMETHOD_(BOOL,HasUserCancelled)(THIS) PURE; + STDMETHOD(SetProgress)(THIS_ DWORD dwCompleted, DWORD dwTotal) PURE; + STDMETHOD(SetProgress64)(THIS_ ULONGLONG ullCompleted, ULONGLONG ullTotal) PURE; + STDMETHOD(SetLine)(THIS_ DWORD dwLineNum, LPCWSTR pwzString, BOOL bPath, LPCVOID reserved) PURE; + STDMETHOD(SetCancelMsg)(THIS_ LPCWSTR pwzCancelMsg, LPCVOID reserved) PURE; + STDMETHOD(Timer)(THIS_ DWORD dwTimerAction, LPCVOID reserved) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IProgressDialog_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IProgressDialog_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IProgressDialog_Release(p) (p)->lpVtbl->Release(p) +/*** IProgressDialog methods ***/ +#define IProgressDialog_StartProgressDialog(p,a,b,c,d) (p)->lpVtbl->StartProgressDialog(p,a,b,c,d) +#define IProgressDialog_StopProgressDialog(p) (p)->lpVtbl->StopProgressDialog(p) +#define IProgressDialog_SetTitle(p,a) (p)->lpVtbl->SetTitle(p,a) +#define IProgressDialog_SetAnimation(p,a,b) (p)->lpVtbl->SetAnimation(p,a,b) +#define IProgressDialog_HasUserCancelled(p) (p)->lpVtbl->HasUserCancelled(p) +#define IProgressDialog_SetProgress(p,a,b) (p)->lpVtbl->SetProgress(p,a,b) +#define IProgressDialog_SetProgress64(p,a,b) (p)->lpVtbl->SetProgress64(p,a,b) +#define IProgressDialog_SetLine(p,a,b,c,d) (p)->lpVtbl->SetLine(p,a,b,c,d) +#define IProgressDialog_SetCancelMsg(p,a,b) (p)->lpVtbl->SetCancelMsg(p,a,b) +#define IProgressDialog_Timer(p,a,b) (p)->lpVtbl->Timer(p,a,b) +#endif + /**************************************************************************** * SHAddToRecentDocs API diff --git a/include/shlwapi.h b/include/shlwapi.h index 21b1e99ddd7..94d98c8fb61 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -83,10 +83,10 @@ DWORD WINAPI SHCopyKeyA(HKEY,LPCSTR,HKEY,DWORD); DWORD WINAPI SHCopyKeyW(HKEY,LPCWSTR,HKEY,DWORD); #define SHCopyKey WINELIB_NAME_AW(SHCopyKey) -/* Undocumented registry functions */ - HKEY WINAPI SHRegDuplicateHKey(HKEY); +/* Undocumented registry functions */ + DWORD WINAPI SHDeleteOrphanKeyA(HKEY,LPCSTR); DWORD WINAPI SHDeleteOrphanKeyW(HKEY,LPCWSTR); #define SHDeleteOrphanKey WINELIB_NAME_AW(SHDeleteOrphanKey) diff --git a/programs/cmdlgtst/Ko.rc b/programs/cmdlgtst/Ko.rc index 0f8643e0063..a210956cd33 100644 --- a/programs/cmdlgtst/Ko.rc +++ b/programs/cmdlgtst/Ko.rc @@ -3,7 +3,7 @@ * Korean Language Support * * Copyright (c) 1999 Eric Williams. - * Copyright 2005 YunSong Hwang + * Copyright 2005,2007 YunSong Hwang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -283,9 +283,9 @@ BEGIN AUTORADIOBUTTON "¼¼·Î(&P)", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON AUTORADIOBUTTON "°¡·Î(&L)", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON GROUPBOX "°¡ÀåÀÚ¸®", grp4, 80, 156, 152, 56, BS_GROUPBOX - LTEXT "¿ÞÂÊ(&E):", stc15, 88, 172, 21, 8 + LTEXT "¿ÞÂÊ(&E):", stc15, 85, 172, 24, 8 EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER - LTEXT "¿À¸¥ÂÊ(&R):", stc16, 159, 172, 27, 8 + LTEXT "¿À¸¥ÂÊ(&R):", stc16, 155, 172, 31, 8 EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER LTEXT "À§(&O):", stc17, 88, 192, 21, 8 EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER diff --git a/programs/winedbg/source.c b/programs/winedbg/source.c index c1fb2eb2d82..eb9576d08c0 100644 --- a/programs/winedbg/source.c +++ b/programs/winedbg/source.c @@ -70,9 +70,9 @@ void source_add_path(const char* path) size = strlen(path) + 1; if (search_path) { - unsigned pos = HeapSize(GetProcessHeap(), 0, search_path); + unsigned pos = strlen(search_path) + 1; new = HeapReAlloc(GetProcessHeap(), 0, search_path, pos + size); - if (!new || !pos) return; + if (!new) return; new[pos - 1] = ';'; strcpy(&new[pos], path); } diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c index 417148e7ce1..8882a1a652b 100644 --- a/programs/winhelp/hlpfile.c +++ b/programs/winhelp/hlpfile.c @@ -580,7 +580,11 @@ static BYTE* HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE if (!tmp) return FALSE; HLPFILE_UncompressLZ77(src, src + csz, tmp); dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz); - if (!dst) return FALSE; + if (!dst) + { + HeapFree(GetProcessHeap(), 0, tmp); + return FALSE; + } HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz); if (tmp2 - dst != sz) WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 78ee4b2f98b..d2fd3c1248c 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -113,14 +113,14 @@ UUID *parse_uuid(const char *u) yy_pop_state(); lineno = (int)strtol(yytext, &cptr, 10); if(!lineno) - parser_error("Malformed '#...' line-directive; invalid linenumber\n"); + error_loc("Malformed '#...' line-directive; invalid linenumber\n"); fname = strchr(cptr, '"'); if(!fname) - parser_error("Malformed '#...' line-directive; missing filename\n"); + error_loc("Malformed '#...' line-directive; missing filename\n"); fname++; cptr = strchr(fname, '"'); if(!cptr) - parser_error("Malformed '#...' line-directive; missing terminating \""); + error_loc("Malformed '#...' line-directive; missing terminating \"\n"); *cptr = '\0'; line_number = lineno - 1; /* We didn't read the newline */ free( input_name ); @@ -414,7 +414,7 @@ int do_import(char *fname) first_import = import; if (!(path = wpp_find_include( fname, input_name ))) - parser_error("Unable to open include file %s\n", fname); + error_loc("Unable to open include file %s\n", fname); import_stack[ptr].temp_name = temp_name; import_stack[ptr].input_name = input_name; @@ -427,7 +427,7 @@ int do_import(char *fname) if (ret) exit(1); if((f = fopen(temp_name, "r")) == NULL) - parser_error("Unable to open %s\n", temp_name); + error_loc("Unable to open %s\n", temp_name); import_stack[ptr].state = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 6a93995d0d1..11ddd45baf1 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -423,7 +423,7 @@ m_attributes: { $$ = NULL; } attributes: '[' attrib_list ']' { $$ = $2; if (!$$) - yyerror("empty attribute lists unsupported"); + error_loc("empty attribute lists unsupported\n"); } ; @@ -513,7 +513,7 @@ attribute: { $$ = NULL; } uuid_string: aUUID | aSTRING { if (!is_valid_uuid($1)) - yyerror("invalid UUID: %s", $1); + error_loc("invalid UUID: %s\n", $1); $$ = parse_uuid($1); } ; @@ -624,7 +624,7 @@ expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); expr_const: expr { $$ = $1; if (!$$->is_const) - yyerror("expression is not constant"); + error_loc("expression is not constant\n"); } ; @@ -658,7 +658,7 @@ funcdef: free($4); $$ = make_func(v, $6); if (is_attr(v->attrs, ATTR_IN)) { - yyerror("inapplicable attribute [in] for function '%s'",$$->def->name); + error_loc("inapplicable attribute [in] for function '%s'\n",$$->def->name); } } ; @@ -721,8 +721,8 @@ int_std: tINT { $$ = make_builtin($1); } coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); - if ($$->defined) yyerror("multiple definition error"); - if ($$->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", $2); + if ($$->defined) error_loc("multiple definition error\n"); + if ($$->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", $2); } ; @@ -755,11 +755,11 @@ dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); $$->kind = dispinterfacehdr: attributes dispinterface { attr_t *attrs; $$ = $2; - if ($$->defined) yyerror("multiple definition error"); + if ($$->defined) error_loc("multiple definition error\n"); attrs = make_attr(ATTR_DISPINTERFACE); $$->attrs = append_attr( $1, attrs ); $$->ref = find_type("IDispatch", 0); - if (!$$->ref) yyerror("IDispatch is undefined"); + if (!$$->ref) error_loc("IDispatch is undefined\n"); $$->defined = TRUE; if (!parse_only && do_header) write_forward($$); } @@ -803,7 +803,7 @@ interfacehdr: attributes interface { $$.interface = $2; $$.old_pointer_default = pointer_default; if (is_attr($1, ATTR_POINTERDEFAULT)) pointer_default = get_attrv($1, ATTR_POINTERDEFAULT); - if ($2->defined) yyerror("multiple definition error"); + if ($2->defined) error_loc("multiple definition error\n"); $2->attrs = $1; $2->defined = TRUE; if (!parse_only && do_header) write_forward($2); @@ -824,7 +824,7 @@ interfacedef: interfacehdr inherit | interfacehdr ':' aIDENTIFIER '{' import int_statements '}' { $$ = $1.interface; $$->ref = find_type2($3, 0); - if (!$$->ref) yyerror("base class '%s' not found in import", $3); + if (!$$->ref) error_loc("base class '%s' not found in import\n", $3); $$->funcs = $6; compute_method_indexes($$); if (!parse_only && do_header) write_interface($$); @@ -1584,7 +1584,7 @@ static type_t *reg_type(type_t *type, const char *name, int t) struct rtype *nt; int hash; if (!name) { - yyerror("registering named type without name"); + error_loc("registering named type without name\n"); return type; } hash = hash_ident(name); @@ -1649,7 +1649,7 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) { pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); - yyerror("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays", + error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", pident->var->name); } } @@ -1691,11 +1691,11 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a if (is_ptr(cur)) cur->type = ptr_type; else - yyerror("'%s': pointer attribute applied to non-pointer type", + error_loc("'%s': pointer attribute applied to non-pointer type\n", cur->name); } else if (is_str && ! is_ptr(cur)) - yyerror("'%s': [string] attribute applied to non-pointer type", + error_loc("'%s': [string] attribute applied to non-pointer type\n", cur->name); if (is_incomplete(cur)) @@ -1712,7 +1712,7 @@ static type_t *find_type(const char *name, int t) while (cur && (cur->t != t || strcmp(cur->name, name))) cur = cur->next; if (!cur) { - yyerror("type '%s' not found", name); + error_loc("type '%s' not found\n", name); return NULL; } return cur->type; @@ -1816,7 +1816,7 @@ static int get_struct_type(var_list_t *fields) { has_conformance = 1; if (field->type->declarray && list_next(fields, &field->entry)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); } if (field->type->length_is) @@ -1876,7 +1876,7 @@ static int get_struct_type(var_list_t *fields) case RPC_FC_CPSTRUCT: has_conformance = 1; if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); has_pointer = 1; break; @@ -1884,7 +1884,7 @@ static int get_struct_type(var_list_t *fields) case RPC_FC_CSTRUCT: has_conformance = 1; if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); break; @@ -1893,8 +1893,7 @@ static int get_struct_type(var_list_t *fields) break; default: - fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", - field->name, t->type); + error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, t->type); /* fallthru - treat it as complex */ /* as soon as we see one of these these members, it's bogus... */ @@ -1936,7 +1935,7 @@ static var_t *reg_const(var_t *var) struct rconst *nc; int hash; if (!var->name) { - yyerror("registering constant without name"); + error_loc("registering constant without name\n"); return var; } hash = hash_ident(var->name); @@ -1954,7 +1953,7 @@ static var_t *find_const(char *name, int f) while (cur && strcmp(cur->name, name)) cur = cur->next; if (!cur) { - if (f) yyerror("constant '%s' not found", name); + if (f) error_loc("constant '%s' not found\n", name); return NULL; } return cur->var; @@ -2054,7 +2053,7 @@ static void check_arg(var_t *arg) type_t *t = arg->type; if (t->type == 0 && ! is_var_ptr(arg)) - yyerror("argument '%s' has void type", arg->name); + error_loc("argument '%s' has void type\n", arg->name); } static void check_all_user_types(ifref_list_t *ifrefs) diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 0255923e834..3c8d6efdc1e 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -509,7 +509,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset) gen_stub(iface, cur, cname, *proc_offset); *proc_offset += get_size_procformatstring_func( cur ); if (midx == -1) midx = idx; - else if (midx != idx) parser_error("method index mismatch in write_proxy\n"); + else if (midx != idx) error("method index mismatch in write_proxy\n"); midx++; } } diff --git a/tools/widl/utils.c b/tools/widl/utils.c index 1382597dfea..7dafc10635d 100644 --- a/tools/widl/utils.c +++ b/tools/widl/utils.c @@ -65,16 +65,27 @@ static void generic_msg(const char *s, const char *t, const char *n, va_list ap) } +/* yyerror: yacc assumes this is not newline terminated. */ int parser_error(const char *s, ...) { va_list ap; va_start(ap, s); generic_msg(s, "Error", parser_text, ap); + fprintf(stderr, "\n"); va_end(ap); exit(1); return 1; } +void error_loc(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + generic_msg(s, "Error", parser_text, ap); + va_end(ap); + exit(1); +} + int parser_warning(const char *s, ...) { va_list ap; diff --git a/tools/widl/utils.h b/tools/widl/utils.h index 37f12f09ca7..c9cc2ba7458 100644 --- a/tools/widl/utils.h +++ b/tools/widl/utils.h @@ -35,6 +35,7 @@ char *xstrdup(const char *str); int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2))); int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2))); +void error_loc(const char *s, ...) __attribute__((format (printf, 1, 2))); void error(const char *s, ...) __attribute__((format (printf, 1, 2))); void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); diff --git a/tools/wine.inf b/tools/wine.inf index 80715fa6bc0..e61d4fb370a 100644 --- a/tools/wine.inf +++ b/tools/wine.inf @@ -2152,6 +2152,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,browseui.dll,1 11,,comcat.dll,1 11,,comctl32.dll,2 +11,,cryptnet.dll,1 11,,d3dxof.dll,1 11,,ddraw.dll,1 11,,ddrawex.dll,1 -- 2.11.4.GIT