diff --git a/dll/win32/ieframe/dochost.c b/dll/win32/ieframe/dochost.c index 61c8234952d..c5a119b2a33 100644 --- a/dll/win32/ieframe/dochost.c +++ b/dll/win32/ieframe/dochost.c @@ -16,12 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "ieframe.h" #include "exdispid.h" +#include "initguid.h" +#include "mshtmdid.h" #include "mshtml.h" #include "perhist.h" -#include "initguid.h" #include "wine/debug.h" @@ -29,14 +32,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(ieframe); DEFINE_OLEGUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0); -#define DOCHOST_DOCCANNAVIGATE 0 +#define DOCHOST_DOCCANNAVIGATE 0 /* Undocumented notification, see mshtml tests */ #define CMDID_EXPLORER_UPDATEHISTORY 38 static ATOM doc_view_atom = 0; -void push_dochost_task(DocHost *This, task_header_t *task, task_proc_t proc, task_destr_t destr, BOOL send) +void +push_dochost_task(DocHost *This, task_header_t *task, task_proc_t proc, task_destr_t destr, BOOL send) { BOOL is_empty; @@ -46,17 +50,19 @@ void push_dochost_task(DocHost *This, task_header_t *task, task_proc_t proc, tas is_empty = list_empty(&This->task_queue); list_add_tail(&This->task_queue, &task->entry); - if(send) + if (send) SendMessageW(This->frame_hwnd, WM_DOCHOSTTASK, 0, 0); - else if(is_empty) + else if (is_empty) PostMessageW(This->frame_hwnd, WM_DOCHOSTTASK, 0, 0); } -LRESULT process_dochost_tasks(DocHost *This) +LRESULT +process_dochost_tasks(DocHost *This) { task_header_t *task; - while(!list_empty(&This->task_queue)) { + while (!list_empty(&This->task_queue)) + { task = LIST_ENTRY(This->task_queue.next, task_header_t, entry); list_remove(&task->entry); @@ -67,12 +73,14 @@ LRESULT process_dochost_tasks(DocHost *This) return 0; } -void abort_dochost_tasks(DocHost *This, task_proc_t proc) +void +abort_dochost_tasks(DocHost *This, task_proc_t proc) { task_header_t *task, *cursor; - LIST_FOR_EACH_ENTRY_SAFE(task, cursor, &This->task_queue, task_header_t, entry) { - if(proc && proc != task->proc) + LIST_FOR_EACH_ENTRY_SAFE(task, cursor, &This->task_queue, task_header_t, entry) + { + if (proc && proc != task->proc) continue; list_remove(&task->entry); @@ -80,12 +88,48 @@ void abort_dochost_tasks(DocHost *This, task_proc_t proc) } } -void on_commandstate_change(DocHost *doc_host, LONG command, BOOL enable) +static BOOL +fire_titlechange(DocHost *This) +{ + IHTMLDocument2 *doc; + BSTR title = NULL; + DISPPARAMS dp = {NULL, NULL, 0, 0}; + HRESULT hres; + BOOL has_title = FALSE; + VARIANTARG arg; + + if (!This->document) + return FALSE; + + hres = IUnknown_QueryInterface(This->document, &IID_IHTMLDocument2, (void **)&doc); + if (FAILED(hres)) + return FALSE; + + hres = IHTMLDocument2_get_title(doc, &title); + IHTMLDocument2_Release(doc); + if (FAILED(hres) || !title) + return FALSE; + + has_title = *title != 0; + + VariantInit(&arg); + V_VT(&arg) = VT_BSTR; + V_BSTR(&arg) = title; + dp.rgvarg = &arg; + dp.cArgs = 1; + call_sink(This->cps.wbe2, DISPID_TITLECHANGE, &dp); + VariantClear(&arg); + + return has_title; +} + +void +on_commandstate_change(DocHost *doc_host, LONG command, BOOL enable) { DISPPARAMS dispparams; VARIANTARG params[2]; - TRACE("command=%d enable=%d\n", command, enable); + TRACE("command=%ld enable=%d\n", command, enable); dispparams.cArgs = 2; dispparams.cNamedArgs = 0; @@ -95,15 +139,16 @@ void on_commandstate_change(DocHost *doc_host, LONG command, BOOL enable) V_VT(params) = VT_BOOL; V_BOOL(params) = enable ? VARIANT_TRUE : VARIANT_FALSE; - V_VT(params+1) = VT_I4; - V_I4(params+1) = command; + V_VT(params + 1) = VT_I4; + V_I4(params + 1) = command; call_sink(doc_host->cps.wbe2, DISPID_COMMANDSTATECHANGE, &dispparams); doc_host->container_vtbl->on_command_state_change(doc_host, command, enable); } -void update_navigation_commands(DocHost *dochost) +void +update_navigation_commands(DocHost *dochost) { unsigned pos = dochost->travellog.loading_pos == -1 ? dochost->travellog.position : dochost->travellog.loading_pos; @@ -111,7 +156,8 @@ void update_navigation_commands(DocHost *dochost) on_commandstate_change(dochost, CSC_NAVIGATEFORWARD, pos < dochost->travellog.length); } -static void notif_complete(DocHost *This, DISPID dispid) +static void +notif_complete(DocHost *This, DISPID dispid) { DISPPARAMS dispparams; VARIANTARG params[2]; @@ -122,81 +168,90 @@ static void notif_complete(DocHost *This, DISPID dispid) dispparams.rgdispidNamedArgs = NULL; dispparams.rgvarg = params; - V_VT(params) = (VT_BYREF|VT_VARIANT); + V_VT(params) = (VT_BYREF | VT_VARIANT); V_BYREF(params) = &url; - V_VT(params+1) = VT_DISPATCH; - V_DISPATCH(params+1) = (IDispatch*)This->wb; + V_VT(params + 1) = VT_DISPATCH; + V_DISPATCH(params + 1) = (IDispatch *)This->wb; V_VT(&url) = VT_BSTR; V_BSTR(&url) = SysAllocString(This->url); - TRACE("%d >>>\n", dispid); + TRACE("%ld >>>\n", dispid); call_sink(This->cps.wbe2, dispid, &dispparams); - TRACE("%d <<<\n", dispid); + TRACE("%ld <<<\n", dispid); SysFreeString(V_BSTR(&url)); } -static void object_available(DocHost *This) +static void +object_available(DocHost *This) { IHlinkTarget *hlink; HRESULT hres; TRACE("(%p)\n", This); - if(!This->document) { + if (!This->document) + { WARN("document == NULL\n"); return; } - hres = IUnknown_QueryInterface(This->document, &IID_IHlinkTarget, (void**)&hlink); - if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(This->document, &IID_IHlinkTarget, (void **)&hlink); + if (SUCCEEDED(hres)) + { hres = IHlinkTarget_Navigate(hlink, 0, NULL); IHlinkTarget_Release(hlink); - if(FAILED(hres)) + if (FAILED(hres)) FIXME("Navigate failed\n"); - }else { + } + else + { IOleObject *ole_object; RECT rect; TRACE("No IHlink iface\n"); - hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void**)&ole_object); - if(FAILED(hres)) { - FIXME("Could not get IOleObject iface: %08x\n", hres); + hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void **)&ole_object); + if (FAILED(hres)) + { + FIXME("Could not get IOleObject iface: %08lx\n", hres); return; } GetClientRect(This->hwnd, &rect); hres = IOleObject_DoVerb(ole_object, OLEIVERB_SHOW, NULL, &This->IOleClientSite_iface, -1, This->hwnd, &rect); IOleObject_Release(ole_object); - if(FAILED(hres)) - FIXME("DoVerb failed: %08x\n", hres); + if (FAILED(hres)) + FIXME("DoVerb failed: %08lx\n", hres); } } -static HRESULT get_doc_ready_state(DocHost *This, READYSTATE *ret) +static HRESULT +get_doc_ready_state(DocHost *This, READYSTATE *ret) { - DISPPARAMS dp = {NULL,NULL,0,0}; + DISPPARAMS dp = {NULL, NULL, 0, 0}; IDispatch *disp; EXCEPINFO ei; VARIANT var; HRESULT hres; - hres = IUnknown_QueryInterface(This->document, &IID_IDispatch, (void**)&disp); - if(FAILED(hres)) + hres = IUnknown_QueryInterface(This->document, &IID_IDispatch, (void **)&disp); + if (FAILED(hres)) return hres; - hres = IDispatch_Invoke(disp, DISPID_READYSTATE, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, - &dp, &var, &ei, NULL); + hres = IDispatch_Invoke( + disp, DISPID_READYSTATE, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL); IDispatch_Release(disp); - if(FAILED(hres)) { - WARN("Invoke(DISPID_READYSTATE failed: %08x\n", hres); + if (FAILED(hres)) + { + WARN("Invoke(DISPID_READYSTATE failed: %08lx\n", hres); return hres; } - if(V_VT(&var) != VT_I4) { + if (V_VT(&var) != VT_I4) + { WARN("V_VT(var) = %d\n", V_VT(&var)); VariantClear(&var); return E_FAIL; @@ -206,83 +261,94 @@ static HRESULT get_doc_ready_state(DocHost *This, READYSTATE *ret) return S_OK; } -static void advise_prop_notif(DocHost *This, BOOL set) +static void +advise_prop_notif(DocHost *This, BOOL set) { IConnectionPointContainer *cp_container; IConnectionPoint *cp; HRESULT hres; - hres = IUnknown_QueryInterface(This->document, &IID_IConnectionPointContainer, (void**)&cp_container); - if(FAILED(hres)) + hres = IUnknown_QueryInterface(This->document, &IID_IConnectionPointContainer, (void **)&cp_container); + if (FAILED(hres)) return; hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &IID_IPropertyNotifySink, &cp); IConnectionPointContainer_Release(cp_container); - if(FAILED(hres)) + if (FAILED(hres)) return; - if(set) - hres = IConnectionPoint_Advise(cp, (IUnknown*)&This->IPropertyNotifySink_iface, &This->prop_notif_cookie); + if (set) + hres = IConnectionPoint_Advise(cp, (IUnknown *)&This->IPropertyNotifySink_iface, &This->prop_notif_cookie); else hres = IConnectionPoint_Unadvise(cp, This->prop_notif_cookie); IConnectionPoint_Release(cp); - if(SUCCEEDED(hres)) + if (SUCCEEDED(hres)) This->is_prop_notif = set; } -void set_doc_state(DocHost *This, READYSTATE doc_state) +void +set_doc_state(DocHost *This, READYSTATE doc_state) { This->doc_state = doc_state; - if(doc_state > This->ready_state) + if (doc_state > This->ready_state) This->ready_state = doc_state; } -static void update_ready_state(DocHost *This, READYSTATE ready_state) +static void +update_ready_state(DocHost *This, READYSTATE ready_state) { - if(ready_state > READYSTATE_LOADING && This->travellog.loading_pos != -1) { + if (ready_state > READYSTATE_LOADING && This->travellog.loading_pos != -1) + { WARN("histupdate not notified\n"); This->travellog.position = This->travellog.loading_pos; This->travellog.loading_pos = -1; } - if(ready_state > READYSTATE_LOADING && This->doc_state <= READYSTATE_LOADING && !This->browser_service /* FIXME */) + if (ready_state > READYSTATE_LOADING && This->doc_state <= READYSTATE_LOADING && !This->browser_service /* FIXME */) notif_complete(This, DISPID_NAVIGATECOMPLETE2); - if(ready_state == READYSTATE_COMPLETE && This->doc_state < READYSTATE_COMPLETE) { + if (ready_state == READYSTATE_COMPLETE && This->doc_state < READYSTATE_COMPLETE) + { set_doc_state(This, READYSTATE_COMPLETE); - if(!This->browser_service) /* FIXME: Not fully correct */ + if (!This->browser_service) /* FIXME: Not fully correct */ notif_complete(This, DISPID_DOCUMENTCOMPLETE); - }else { + } + else + { set_doc_state(This, ready_state); } } -typedef struct { +typedef struct +{ task_header_t header; IUnknown *doc; READYSTATE ready_state; } ready_state_task_t; -static void ready_state_task_destr(task_header_t *_task) +static void +ready_state_task_destr(task_header_t *_task) { - ready_state_task_t *task = (ready_state_task_t*)_task; + ready_state_task_t *task = (ready_state_task_t *)_task; IUnknown_Release(task->doc); - heap_free(task); + free(task); } -static void ready_state_proc(DocHost *This, task_header_t *_task) +static void +ready_state_proc(DocHost *This, task_header_t *_task) { - ready_state_task_t *task = (ready_state_task_t*)_task; + ready_state_task_t *task = (ready_state_task_t *)_task; - if(task->doc == This->document) + if (task->doc == This->document) update_ready_state(This, task->ready_state); } -static void push_ready_state_task(DocHost *This, READYSTATE ready_state) +static void +push_ready_state_task(DocHost *This, READYSTATE ready_state) { - ready_state_task_t *task = heap_alloc(sizeof(ready_state_task_t)); + ready_state_task_t *task = malloc(sizeof(ready_state_task_t)); IUnknown_AddRef(This->document); task->doc = This->document; @@ -291,17 +357,20 @@ static void push_ready_state_task(DocHost *This, READYSTATE ready_state) push_dochost_task(This, &task->header, ready_state_proc, ready_state_task_destr, FALSE); } -static void object_available_task_destr(task_header_t *task) +static void +object_available_task_destr(task_header_t *task) { - heap_free(task); + free(task); } -static void object_available_proc(DocHost *This, task_header_t *task) +static void +object_available_proc(DocHost *This, task_header_t *task) { object_available(This); } -HRESULT dochost_object_available(DocHost *This, IUnknown *doc) +HRESULT +dochost_object_available(DocHost *This, IUnknown *doc) { READYSTATE ready_state; task_header_t *task; @@ -311,36 +380,43 @@ HRESULT dochost_object_available(DocHost *This, IUnknown *doc) IUnknown_AddRef(doc); This->document = doc; - hres = IUnknown_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj); - if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(doc, &IID_IOleObject, (void **)&oleobj); + if (SUCCEEDED(hres)) + { CLSID clsid; hres = IOleObject_GetUserClassID(oleobj, &clsid); - if(SUCCEEDED(hres)) - TRACE("Got clsid %s\n", - IsEqualGUID(&clsid, &CLSID_HTMLDocument) ? "CLSID_HTMLDocument" : debugstr_guid(&clsid)); + if (SUCCEEDED(hres)) + TRACE( + "Got clsid %s\n", + IsEqualGUID(&clsid, &CLSID_HTMLDocument) ? "CLSID_HTMLDocument" : debugstr_guid(&clsid)); hres = IOleObject_SetClientSite(oleobj, &This->IOleClientSite_iface); - if(FAILED(hres)) - FIXME("SetClientSite failed: %08x\n", hres); + if (FAILED(hres)) + FIXME("SetClientSite failed: %08lx\n", hres); IOleObject_Release(oleobj); - }else { - FIXME("Could not get IOleObject iface: %08x\n", hres); + } + else + { + FIXME("Could not get IOleObject iface: %08lx\n", hres); } /* FIXME: Call SetAdvise */ - task = heap_alloc(sizeof(*task)); + task = malloc(sizeof(*task)); push_dochost_task(This, task, object_available_proc, object_available_task_destr, FALSE); hres = get_doc_ready_state(This, &ready_state); - if(SUCCEEDED(hres)) { - if(ready_state == READYSTATE_COMPLETE) + if (SUCCEEDED(hres)) + { + if (ready_state == READYSTATE_COMPLETE) push_ready_state_task(This, READYSTATE_COMPLETE); - if(ready_state != READYSTATE_COMPLETE || This->doc_navigate) + if (ready_state != READYSTATE_COMPLETE || This->doc_navigate) advise_prop_notif(This, TRUE); - }else if(!This->doc_navigate) { + } + else if (!This->doc_navigate) + { /* If we can't get document's ready state, there is not much we can do. * Assume that document is complete at this point. */ push_ready_state_task(This, READYSTATE_COMPLETE); @@ -349,61 +425,72 @@ HRESULT dochost_object_available(DocHost *This, IUnknown *doc) return S_OK; } -static LRESULT resize_document(DocHost *This, LONG width, LONG height) +static LRESULT +resize_document(DocHost *This, LONG width, LONG height) { RECT rect = {0, 0, width, height}; - TRACE("(%p)->(%d %d)\n", This, width, height); + TRACE("(%p)->(%ld %ld)\n", This, width, height); - if(This->view) + if (This->view) IOleDocumentView_SetRect(This->view, &rect); return 0; } -static LRESULT WINAPI doc_view_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +static LRESULT WINAPI +doc_view_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { DocHost *This; - static const WCHAR wszTHIS[] = {'T','H','I','S',0}; - - if(msg == WM_CREATE) { - This = *(DocHost**)lParam; - SetPropW(hwnd, wszTHIS, This); - }else { - This = GetPropW(hwnd, wszTHIS); + if (msg == WM_CREATE) + { + This = *(DocHost **)lParam; + SetPropW(hwnd, L"THIS", This); + } + else + { + This = GetPropW(hwnd, L"THIS"); } - switch(msg) { - case WM_SIZE: - return resize_document(This, LOWORD(lParam), HIWORD(lParam)); + switch (msg) + { + case WM_SIZE: + return resize_document(This, LOWORD(lParam), HIWORD(lParam)); } return DefWindowProcW(hwnd, msg, wParam, lParam); } -static void free_travellog_entry(travellog_entry_t *entry) +static void +free_travellog_entry(travellog_entry_t *entry) { - if(entry->stream) + if (entry->stream) + { IStream_Release(entry->stream); - heap_free(entry->url); + entry->stream = NULL; + } + free(entry->url); + entry->url = NULL; } -static IStream *get_travellog_stream(DocHost *This) +static IStream * +get_travellog_stream(DocHost *This) { IPersistHistory *persist_history; IStream *stream; HRESULT hres; - hres = IUnknown_QueryInterface(This->document, &IID_IPersistHistory, (void**)&persist_history); - if(FAILED(hres)) + hres = IUnknown_QueryInterface(This->document, &IID_IPersistHistory, (void **)&persist_history); + if (FAILED(hres)) return NULL; hres = CreateStreamOnHGlobal(NULL, TRUE, &stream); - if(SUCCEEDED(hres)) + if (SUCCEEDED(hres)) hres = IPersistHistory_SaveHistory(persist_history, stream); IPersistHistory_Release(persist_history); - if(FAILED(hres)) { + if (FAILED(hres)) + { IStream_Release(stream); return NULL; } @@ -411,88 +498,103 @@ static IStream *get_travellog_stream(DocHost *This) return stream; } -static void dump_travellog(DocHost *This) +static void +dump_travellog(DocHost *This) { unsigned i; - for(i=0; i < This->travellog.length; i++) + for (i = 0; i < This->travellog.length; i++) TRACE("%d: %s %s\n", i, i == This->travellog.position ? "=>" : " ", debugstr_w(This->travellog.log[i].url)); - if(i == This->travellog.position) + if (i == This->travellog.position) TRACE("%d: =>\n", i); } -static void update_travellog(DocHost *This) +static void +update_travellog(DocHost *This) { travellog_entry_t *new_entry; - static const WCHAR about_schemeW[] = {'a','b','o','u','t',':'}; + static const WCHAR about_schemeW[] = {'a', 'b', 'o', 'u', 't', ':'}; - if(This->url && !_wcsnicmp(This->url, about_schemeW, ARRAY_SIZE(about_schemeW))) { + if (This->url && !_wcsnicmp(This->url, about_schemeW, ARRAY_SIZE(about_schemeW))) + { TRACE("Skipping about URL\n"); return; } - if(!This->travellog.log) { - This->travellog.log = heap_alloc(4 * sizeof(*This->travellog.log)); - if(!This->travellog.log) + if (!This->travellog.log) + { + This->travellog.log = malloc(4 * sizeof(*This->travellog.log)); + if (!This->travellog.log) return; This->travellog.size = 4; - }else if(This->travellog.size < This->travellog.position+1) { + } + else if (This->travellog.size < This->travellog.position + 2) + { travellog_entry_t *new_travellog; - new_travellog = heap_realloc(This->travellog.log, This->travellog.size*2*sizeof(*This->travellog.log)); - if(!new_travellog) + new_travellog = realloc(This->travellog.log, This->travellog.size * 2 * sizeof(*This->travellog.log)); + if (!new_travellog) return; This->travellog.log = new_travellog; This->travellog.size *= 2; } - if(This->travellog.loading_pos == -1) { + if (This->travellog.loading_pos == -1) + { /* Clear forward history. */ - while(This->travellog.length > This->travellog.position) + while (This->travellog.length > This->travellog.position) free_travellog_entry(This->travellog.log + --This->travellog.length); } new_entry = This->travellog.log + This->travellog.position; - new_entry->url = heap_strdupW(This->url); + new_entry->url = _wcsdup(This->url); TRACE("Adding %s at %d\n", debugstr_w(This->url), This->travellog.position); - if(!new_entry->url) + if (!new_entry->url) return; new_entry->stream = get_travellog_stream(This); - if(This->travellog.loading_pos == -1) { + if (This->travellog.loading_pos == -1) + { This->travellog.position++; - }else { - This->travellog.position = This->travellog.loading_pos; - This->travellog.loading_pos = -1; + assert(This->travellog.position < This->travellog.size); + This->travellog.log[This->travellog.position].stream = NULL; + This->travellog.log[This->travellog.position].url = NULL; } - if(This->travellog.position > This->travellog.length) + else + { + This->travellog.position = This->travellog.loading_pos; + This->travellog.loading_pos = -1; + } + if (This->travellog.position > This->travellog.length) This->travellog.length = This->travellog.position; dump_travellog(This); } -void create_doc_view_hwnd(DocHost *This) +void +create_doc_view_hwnd(DocHost *This) { RECT rect; - static const WCHAR wszShell_DocObject_View[] = - {'S','h','e','l','l',' ','D','o','c','O','b','j','e','c','t',' ','V','i','e','w',0}; - - if(!doc_view_atom) { - static WNDCLASSEXW wndclass = { - sizeof(wndclass), - CS_PARENTDC, - doc_view_proc, - 0, 0 /* native uses 4*/, NULL, NULL, NULL, - (HBRUSH)(COLOR_WINDOW + 1), NULL, - wszShell_DocObject_View, - NULL - }; + if (!doc_view_atom) + { + static WNDCLASSEXW wndclass = {sizeof(wndclass), + CS_PARENTDC, + doc_view_proc, + 0, + 0 /* native uses 4*/, + NULL, + NULL, + NULL, + (HBRUSH)(COLOR_WINDOW + 1), + NULL, + L"Shell DocObject View", + NULL}; wndclass.hInstance = ieframe_instance; @@ -500,41 +602,44 @@ void create_doc_view_hwnd(DocHost *This) } This->container_vtbl->get_docobj_rect(This, &rect); - This->hwnd = CreateWindowExW(0, wszShell_DocObject_View, - wszShell_DocObject_View, - WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP, - rect.left, rect.top, rect.right, rect.bottom, This->frame_hwnd, - NULL, ieframe_instance, This); + This->hwnd = CreateWindowExW( + 0, L"Shell DocObject View", L"Shell DocObject View", + WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP, rect.left, rect.top, rect.right, + rect.bottom, This->frame_hwnd, NULL, ieframe_instance, This); } -void deactivate_document(DocHost *This) +void +deactivate_document(DocHost *This) { IOleInPlaceObjectWindowless *winobj; IOleObject *oleobj = NULL; IHlinkTarget *hlink = NULL; HRESULT hres; - if(!This->document) return; + if (!This->document) + return; - if(This->doc_navigate) { + if (This->doc_navigate) + { IUnknown_Release(This->doc_navigate); This->doc_navigate = NULL; } - if(This->is_prop_notif) + if (This->is_prop_notif) advise_prop_notif(This, FALSE); - if(This->view) + if (This->view) IOleDocumentView_UIActivate(This->view, FALSE); - hres = IUnknown_QueryInterface(This->document, &IID_IOleInPlaceObjectWindowless, - (void**)&winobj); - if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(This->document, &IID_IOleInPlaceObjectWindowless, (void **)&winobj); + if (SUCCEEDED(hres)) + { IOleInPlaceObjectWindowless_InPlaceDeactivate(winobj); IOleInPlaceObjectWindowless_Release(winobj); } - if(This->view) { + if (This->view) + { IOleDocumentView_Show(This->view, FALSE); IOleDocumentView_CloseView(This->view, 0); IOleDocumentView_SetInPlaceSite(This->view, NULL); @@ -542,22 +647,25 @@ void deactivate_document(DocHost *This) This->view = NULL; } - hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void**)&oleobj); - if(SUCCEEDED(hres)) + hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void **)&oleobj); + if (SUCCEEDED(hres)) IOleObject_Close(oleobj, OLECLOSE_NOSAVE); - hres = IUnknown_QueryInterface(This->document, &IID_IHlinkTarget, (void**)&hlink); - if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(This->document, &IID_IHlinkTarget, (void **)&hlink); + if (SUCCEEDED(hres)) + { IHlinkTarget_SetBrowseContext(hlink, NULL); IHlinkTarget_Release(hlink); } - if(oleobj) { + if (oleobj) + { IOleClientSite *client_site = NULL; IOleObject_GetClientSite(oleobj, &client_site); - if(client_site) { - if(client_site == &This->IOleClientSite_iface) + if (client_site) + { + if (client_site == &This->IOleClientSite_iface) IOleObject_SetClientSite(oleobj, NULL); IOleClientSite_Release(client_site); } @@ -569,260 +677,329 @@ void deactivate_document(DocHost *This) This->document = NULL; } -HRESULT refresh_document(DocHost *This, const VARIANT *level) +HRESULT +refresh_document(DocHost *This, const VARIANT *level) { IOleCommandTarget *cmdtrg; VARIANT vin, vout; HRESULT hres; - if(level && (V_VT(level) != VT_I4 || V_I4(level) != REFRESH_NORMAL)) + if (level && (V_VT(level) != VT_I4 || V_I4(level) != REFRESH_NORMAL)) FIXME("Unsupported refresh level %s\n", debugstr_variant(level)); - if(!This->document) { + if (!This->document) + { FIXME("no document\n"); return E_FAIL; } - hres = IUnknown_QueryInterface(This->document, &IID_IOleCommandTarget, (void**)&cmdtrg); - if(FAILED(hres)) + hres = IUnknown_QueryInterface(This->document, &IID_IOleCommandTarget, (void **)&cmdtrg); + if (FAILED(hres)) return hres; V_VT(&vin) = VT_EMPTY; V_VT(&vout) = VT_EMPTY; hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_REFRESH, OLECMDEXECOPT_PROMPTUSER, &vin, &vout); IOleCommandTarget_Release(cmdtrg); - if(FAILED(hres)) + if (FAILED(hres)) return hres; VariantClear(&vout); return S_OK; } -void release_dochost_client(DocHost *This) +void +activate_document(DocHost *This) { - if(This->hwnd) { + IOleObject *oleobj; + IHlinkTarget *hlink; + HRESULT hres; + + if (!This->document) + return; + + hres = IUnknown_QueryInterface(This->document, &IID_IHlinkTarget, (void **)&hlink); + if (SUCCEEDED(hres)) + { + IHlinkTarget_Navigate(hlink, 0, NULL); + IHlinkTarget_Release(hlink); + } + + hres = IUnknown_QueryInterface(This->document, &IID_IOleObject, (void **)&oleobj); + if (SUCCEEDED(hres)) + { + IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, NULL, -1, 0, NULL); + IOleObject_Release(oleobj); + } + + refresh_document(This, NULL); + + if (This->view) + IOleDocumentView_UIActivate(This->view, TRUE); +} + +void +release_dochost_client(DocHost *This) +{ + if (This->hwnd) + { DestroyWindow(This->hwnd); This->hwnd = NULL; } - if(This->hostui) { + if (This->hostui) + { IDocHostUIHandler_Release(This->hostui); This->hostui = NULL; } - if(This->client_disp) { + if (This->client_disp) + { IDispatch_Release(This->client_disp); This->client_disp = NULL; } - if(This->frame) { + if (This->frame) + { IOleInPlaceFrame_Release(This->frame); This->frame = NULL; } - if(This->olecmd) { + if (This->olecmd) + { IOleCommandTarget_Release(This->olecmd); This->olecmd = NULL; } } -static inline DocHost *impl_from_IOleCommandTarget(IOleCommandTarget *iface) +static inline DocHost * +impl_from_IOleCommandTarget(IOleCommandTarget *iface) { return CONTAINING_RECORD(iface, DocHost, IOleCommandTarget_iface); } -static HRESULT WINAPI ClOleCommandTarget_QueryInterface(IOleCommandTarget *iface, - REFIID riid, void **ppv) +static HRESULT WINAPI +ClOleCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv) { DocHost *This = impl_from_IOleCommandTarget(iface); return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); } -static ULONG WINAPI ClOleCommandTarget_AddRef(IOleCommandTarget *iface) +static ULONG WINAPI +ClOleCommandTarget_AddRef(IOleCommandTarget *iface) { DocHost *This = impl_from_IOleCommandTarget(iface); return IOleClientSite_AddRef(&This->IOleClientSite_iface); } -static ULONG WINAPI ClOleCommandTarget_Release(IOleCommandTarget *iface) +static ULONG WINAPI +ClOleCommandTarget_Release(IOleCommandTarget *iface) { DocHost *This = impl_from_IOleCommandTarget(iface); return IOleClientSite_Release(&This->IOleClientSite_iface); } -static HRESULT WINAPI ClOleCommandTarget_QueryStatus(IOleCommandTarget *iface, - const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +static HRESULT WINAPI +ClOleCommandTarget_QueryStatus( + IOleCommandTarget *iface, + const GUID *pguidCmdGroup, + ULONG cCmds, + OLECMD prgCmds[], + OLECMDTEXT *pCmdText) { DocHost *This = impl_from_IOleCommandTarget(iface); ULONG i; - TRACE("(%p)->(%s %u %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, - pCmdText); - for(i=0; prgCmds && i < cCmds; i++) - TRACE("unsupported command %u (%x)\n", prgCmds[i].cmdID, prgCmds[i].cmdf); + TRACE("(%p)->(%s %lu %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText); + for (i = 0; prgCmds && i < cCmds; i++) + TRACE("unsupported command %lu (%lx)\n", prgCmds[i].cmdID, prgCmds[i].cmdf); return E_NOTIMPL; } -static HRESULT WINAPI ClOleCommandTarget_Exec(IOleCommandTarget *iface, - const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, - VARIANT *pvaOut) +static HRESULT WINAPI +ClOleCommandTarget_Exec( + IOleCommandTarget *iface, + const GUID *pguidCmdGroup, + DWORD nCmdID, + DWORD nCmdexecopt, + VARIANT *pvaIn, + VARIANT *pvaOut) { DocHost *This = impl_from_IOleCommandTarget(iface); - TRACE("(%p)->(%s %d %d %s %s)\n", This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, - debugstr_variant(pvaIn), debugstr_variant(pvaOut)); - - if(!pguidCmdGroup) { - switch(nCmdID) { - case OLECMDID_UPDATECOMMANDS: - if(!This->olecmd) - return E_NOTIMPL; - return IOleCommandTarget_Exec(This->olecmd, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); - case OLECMDID_SETDOWNLOADSTATE: - if(pvaIn && V_VT(pvaIn) == VT_I4) - This->busy = V_I4(pvaIn) ? VARIANT_TRUE : VARIANT_FALSE; - if(This->olecmd) + TRACE( + "(%p)->(%s %ld %ld %s %s)\n", This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, debugstr_variant(pvaIn), + debugstr_variant(pvaOut)); + + if (!pguidCmdGroup) + { + switch (nCmdID) + { + case OLECMDID_UPDATECOMMANDS: + if (!This->olecmd) + return E_NOTIMPL; return IOleCommandTarget_Exec(This->olecmd, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); - - if(!pvaIn || V_VT(pvaIn) != VT_I4) - return E_INVALIDARG; - - notify_download_state(This, V_I4(pvaIn)); - return S_OK; - default: - TRACE("Unimplemented cmdid %d\n", nCmdID); - return E_NOTIMPL; + case OLECMDID_SETTITLE: + if (fire_titlechange(This) && This->olecmd) + return IOleCommandTarget_Exec(This->olecmd, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); + return S_OK; + case OLECMDID_SETDOWNLOADSTATE: + if (pvaIn && V_VT(pvaIn) == VT_I4) + This->busy = V_I4(pvaIn) ? VARIANT_TRUE : VARIANT_FALSE; + if (This->olecmd) + return IOleCommandTarget_Exec(This->olecmd, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); + + if (!pvaIn || V_VT(pvaIn) != VT_I4) + return E_INVALIDARG; + + notify_download_state(This, V_I4(pvaIn)); + return S_OK; + default: + TRACE("Unimplemented cmdid %ld\n", nCmdID); + return E_NOTIMPL; } } - if(IsEqualGUID(pguidCmdGroup, &CGID_DocHostCmdPriv)) { - switch(nCmdID) { - case DOCHOST_DOCCANNAVIGATE: - if(!pvaIn || V_VT(pvaIn) != VT_UNKNOWN) - return E_INVALIDARG; - - if(This->doc_navigate) - IUnknown_Release(This->doc_navigate); - IUnknown_AddRef(V_UNKNOWN(pvaIn)); - This->doc_navigate = V_UNKNOWN(pvaIn); - return S_OK; - - case 1: { - IHTMLWindow2 *win2; - SAFEARRAY *sa = V_ARRAY(pvaIn); - VARIANT status_code, url, htmlwindow; - LONG ind; - HRESULT hres; - - if(V_VT(pvaIn) != VT_ARRAY || !sa || (SafeArrayGetDim(sa) != 1)) - return E_INVALIDARG; - - ind = 0; - hres = SafeArrayGetElement(sa, &ind, &status_code); - if(FAILED(hres) || V_VT(&status_code)!=VT_I4) - return E_INVALIDARG; - - ind = 1; - hres = SafeArrayGetElement(sa, &ind, &url); - if(FAILED(hres) || V_VT(&url)!=VT_BSTR) - return E_INVALIDARG; - - ind = 3; - hres = SafeArrayGetElement(sa, &ind, &htmlwindow); - if(FAILED(hres) || V_VT(&htmlwindow)!=VT_UNKNOWN || !V_UNKNOWN(&htmlwindow)) - return E_INVALIDARG; - - hres = IUnknown_QueryInterface(V_UNKNOWN(&htmlwindow), &IID_IHTMLWindow2, (void**)&win2); - if(FAILED(hres)) - return E_INVALIDARG; - - handle_navigation_error(This, V_I4(&status_code), V_BSTR(&url), win2); - IHTMLWindow2_Release(win2); - return S_OK; - } - - default: - TRACE("unsupported command %d of CGID_DocHostCmdPriv\n", nCmdID); - return E_NOTIMPL; + if (IsEqualGUID(pguidCmdGroup, &CGID_DocHostCmdPriv)) + { + switch (nCmdID) + { + case DOCHOST_DOCCANNAVIGATE: + if (!pvaIn || V_VT(pvaIn) != VT_UNKNOWN) + return E_INVALIDARG; + + if (This->doc_navigate) + IUnknown_Release(This->doc_navigate); + IUnknown_AddRef(V_UNKNOWN(pvaIn)); + This->doc_navigate = V_UNKNOWN(pvaIn); + return S_OK; + + case 1: + { + IHTMLWindow2 *win2; + SAFEARRAY *sa = V_ARRAY(pvaIn); + VARIANT status_code, url, htmlwindow; + LONG ind; + HRESULT hres; + + if (V_VT(pvaIn) != VT_ARRAY || !sa || (SafeArrayGetDim(sa) != 1)) + return E_INVALIDARG; + + ind = 0; + hres = SafeArrayGetElement(sa, &ind, &status_code); + if (FAILED(hres) || V_VT(&status_code) != VT_I4) + return E_INVALIDARG; + + ind = 1; + hres = SafeArrayGetElement(sa, &ind, &url); + if (FAILED(hres) || V_VT(&url) != VT_BSTR) + return E_INVALIDARG; + + ind = 3; + hres = SafeArrayGetElement(sa, &ind, &htmlwindow); + if (FAILED(hres) || V_VT(&htmlwindow) != VT_UNKNOWN || !V_UNKNOWN(&htmlwindow)) + return E_INVALIDARG; + + hres = IUnknown_QueryInterface(V_UNKNOWN(&htmlwindow), &IID_IHTMLWindow2, (void **)&win2); + if (FAILED(hres)) + return E_INVALIDARG; + + handle_navigation_error(This, V_I4(&status_code), V_BSTR(&url), win2); + IHTMLWindow2_Release(win2); + return S_OK; + } + + default: + TRACE("unsupported command %ld of CGID_DocHostCmdPriv\n", nCmdID); + return E_NOTIMPL; } } - if(IsEqualGUID(pguidCmdGroup, &CGID_Explorer)) { - switch(nCmdID) { - case CMDID_EXPLORER_UPDATEHISTORY: - update_travellog(This); - update_navigation_commands(This); - return S_OK; - - default: - TRACE("Unimplemented cmdid %d of CGID_Explorer\n", nCmdID); - return E_NOTIMPL; + if (IsEqualGUID(pguidCmdGroup, &CGID_Explorer)) + { + switch (nCmdID) + { + case CMDID_EXPLORER_UPDATEHISTORY: + update_travellog(This); + update_navigation_commands(This); + return S_OK; + + default: + TRACE("Unimplemented cmdid %ld of CGID_Explorer\n", nCmdID); + return E_NOTIMPL; } } - if(IsEqualGUID(pguidCmdGroup, &CGID_ShellDocView)) { - switch(nCmdID) { - default: - TRACE("Unimplemented cmdid %d of CGID_ShellDocView\n", nCmdID); - return E_NOTIMPL; + if (IsEqualGUID(pguidCmdGroup, &CGID_ShellDocView)) + { + switch (nCmdID) + { + default: + TRACE("Unimplemented cmdid %ld of CGID_ShellDocView\n", nCmdID); + return E_NOTIMPL; } } - if(IsEqualGUID(&CGID_DocHostCommandHandler, pguidCmdGroup)) { - if(!This->olecmd) + if (IsEqualGUID(&CGID_DocHostCommandHandler, pguidCmdGroup)) + { + if (!This->olecmd) return E_NOTIMPL; return IOleCommandTarget_Exec(This->olecmd, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } - TRACE("Unimplemented cmdid %d of group %s\n", nCmdID, debugstr_guid(pguidCmdGroup)); + TRACE("Unimplemented cmdid %ld of group %s\n", nCmdID, debugstr_guid(pguidCmdGroup)); return E_NOTIMPL; } static const IOleCommandTargetVtbl OleCommandTargetVtbl = { - ClOleCommandTarget_QueryInterface, - ClOleCommandTarget_AddRef, - ClOleCommandTarget_Release, - ClOleCommandTarget_QueryStatus, - ClOleCommandTarget_Exec -}; + ClOleCommandTarget_QueryInterface, ClOleCommandTarget_AddRef, ClOleCommandTarget_Release, + ClOleCommandTarget_QueryStatus, ClOleCommandTarget_Exec}; -static inline DocHost *impl_from_IDocHostUIHandler2(IDocHostUIHandler2 *iface) +static inline DocHost * +impl_from_IDocHostUIHandler2(IDocHostUIHandler2 *iface) { return CONTAINING_RECORD(iface, DocHost, IDocHostUIHandler2_iface); } -static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, - REFIID riid, void **ppv) +static HRESULT WINAPI +DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv) { DocHost *This = impl_from_IDocHostUIHandler2(iface); return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); } -static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface) +static ULONG WINAPI +DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface) { DocHost *This = impl_from_IDocHostUIHandler2(iface); return IOleClientSite_AddRef(&This->IOleClientSite_iface); } -static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface) +static ULONG WINAPI +DocHostUIHandler_Release(IDocHostUIHandler2 *iface) { DocHost *This = impl_from_IDocHostUIHandler2(iface); return IOleClientSite_Release(&This->IOleClientSite_iface); } -static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, - DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved) +static HRESULT WINAPI +DocHostUIHandler_ShowContextMenu( + IDocHostUIHandler2 *iface, + DWORD dwID, + POINT *ppt, + IUnknown *pcmdtReserved, + IDispatch *pdispReserved) { DocHost *This = impl_from_IDocHostUIHandler2(iface); HRESULT hres; - TRACE("(%p)->(%d %p %p %p)\n", This, dwID, ppt, pcmdtReserved, pdispReserved); + TRACE("(%p)->(%ld %p %p %p)\n", This, dwID, ppt, pcmdtReserved, pdispReserved); - if(This->hostui) { - hres = IDocHostUIHandler_ShowContextMenu(This->hostui, dwID, ppt, pcmdtReserved, - pdispReserved); - if(hres == S_OK) + if (This->hostui) + { + hres = IDocHostUIHandler_ShowContextMenu(This->hostui, dwID, ppt, pcmdtReserved, pdispReserved); + if (hres == S_OK) return S_OK; } @@ -830,181 +1007,192 @@ static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, - DOCHOSTUIINFO *pInfo) +static HRESULT WINAPI +DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo) { DocHost *This = impl_from_IDocHostUIHandler2(iface); HRESULT hres; TRACE("(%p)->(%p)\n", This, pInfo); - if(This->hostui) { + if (This->hostui) + { hres = IDocHostUIHandler_GetHostInfo(This->hostui, pInfo); - if(SUCCEEDED(hres)) + if (SUCCEEDED(hres)) return hres; } - pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU | DOCHOSTUIFLAG_OPENNEWWIN - | DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 | DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION - | DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION; + pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU | DOCHOSTUIFLAG_OPENNEWWIN | + DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 | DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION | + DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION; return S_OK; } -static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID, - IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, - IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc) +static HRESULT WINAPI +DocHostUIHandler_ShowUI( + IDocHostUIHandler2 *iface, + DWORD dwID, + IOleInPlaceActiveObject *pActiveObject, + IOleCommandTarget *pCommandTarget, + IOleInPlaceFrame *pFrame, + IOleInPlaceUIWindow *pDoc) { DocHost *This = impl_from_IDocHostUIHandler2(iface); - FIXME("(%p)->(%d %p %p %p %p)\n", This, dwID, pActiveObject, pCommandTarget, - pFrame, pDoc); + FIXME("(%p)->(%ld %p %p %p %p)\n", This, dwID, pActiveObject, pCommandTarget, pFrame, pDoc); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface) +static HRESULT WINAPI +DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)\n", This); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface) +static HRESULT WINAPI +DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface) { DocHost *This = impl_from_IDocHostUIHandler2(iface); TRACE("(%p)\n", This); - if(!This->hostui) + if (!This->hostui) return S_FALSE; return IDocHostUIHandler_UpdateUI(This->hostui); } -static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, - BOOL fEnable) +static HRESULT WINAPI +DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)->(%x)\n", This, fEnable); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, - BOOL fActivate) +static HRESULT WINAPI +DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)->(%x)\n", This, fActivate); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, - BOOL fActivate) +static HRESULT WINAPI +DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)->(%x)\n", This, fActivate); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, - LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow) +static HRESULT WINAPI +DocHostUIHandler_ResizeBorder( + IDocHostUIHandler2 *iface, + LPCRECT prcBorder, + IOleInPlaceUIWindow *pUIWindow, + BOOL fRameWindow) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)->(%p %p %X)\n", This, prcBorder, pUIWindow, fRameWindow); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, - LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID) +static HRESULT WINAPI +DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID) { DocHost *This = impl_from_IDocHostUIHandler2(iface); HRESULT hr = S_FALSE; - TRACE("(%p)->(%p %p %d)\n", This, lpMsg, pguidCmdGroup, nCmdID); + TRACE("(%p)->(%p %p %ld)\n", This, lpMsg, pguidCmdGroup, nCmdID); - if(This->hostui) + if (This->hostui) hr = IDocHostUIHandler_TranslateAccelerator(This->hostui, lpMsg, pguidCmdGroup, nCmdID); return hr; } -static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface, - LPOLESTR *pchKey, DWORD dw) +static HRESULT WINAPI +DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface, LPOLESTR *pchKey, DWORD dw) { DocHost *This = impl_from_IDocHostUIHandler2(iface); - TRACE("(%p)->(%p %d)\n", This, pchKey, dw); + TRACE("(%p)->(%p %ld)\n", This, pchKey, dw); - if(This->hostui) + if (This->hostui) return IDocHostUIHandler_GetOptionKeyPath(This->hostui, pchKey, dw); return S_OK; } -static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface, - IDropTarget *pDropTarget, IDropTarget **ppDropTarget) +static HRESULT WINAPI +DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface, IDropTarget *pDropTarget, IDropTarget **ppDropTarget) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)\n", This); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, - IDispatch **ppDispatch) +static HRESULT WINAPI +DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch) { DocHost *This = impl_from_IDocHostUIHandler2(iface); TRACE("(%p)->(%p)\n", This, ppDispatch); - if(This->hostui) + if (This->hostui) return IDocHostUIHandler_GetExternal(This->hostui, ppDispatch); - if(!This->shell_ui_helper) { + if (!This->shell_ui_helper) + { HRESULT hres; hres = create_shell_ui_helper(&This->shell_ui_helper); - if(FAILED(hres)) + if (FAILED(hres)) return hres; } - *ppDispatch = (IDispatch*)This->shell_ui_helper; + *ppDispatch = (IDispatch *)This->shell_ui_helper; IDispatch_AddRef(*ppDispatch); return S_OK; } -static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, - DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut) +static HRESULT WINAPI +DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut) { DocHost *This = impl_from_IDocHostUIHandler2(iface); - TRACE("(%p)->(%d %s %p)\n", This, dwTranslate, debugstr_w(pchURLIn), ppchURLOut); + TRACE("(%p)->(%ld %s %p)\n", This, dwTranslate, debugstr_w(pchURLIn), ppchURLOut); - if(This->hostui) - return IDocHostUIHandler_TranslateUrl(This->hostui, dwTranslate, - pchURLIn, ppchURLOut); + if (This->hostui) + return IDocHostUIHandler_TranslateUrl(This->hostui, dwTranslate, pchURLIn, ppchURLOut); return S_FALSE; } -static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, - IDataObject *pDO, IDataObject **ppDORet) +static HRESULT WINAPI +DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO, IDataObject **ppDORet) { DocHost *This = impl_from_IDocHostUIHandler2(iface); FIXME("(%p)->(%p %p)\n", This, pDO, ppDORet); return E_NOTIMPL; } -static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface, - LPOLESTR *pchKey, DWORD dw) +static HRESULT WINAPI +DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface, LPOLESTR *pchKey, DWORD dw) { DocHost *This = impl_from_IDocHostUIHandler2(iface); IDocHostUIHandler2 *handler; HRESULT hres; - TRACE("(%p)->(%p %d)\n", This, pchKey, dw); + TRACE("(%p)->(%p %ld)\n", This, pchKey, dw); - if(!This->hostui) + if (!This->hostui) return S_OK; - hres = IDocHostUIHandler_QueryInterface(This->hostui, &IID_IDocHostUIHandler2, - (void**)&handler); - if(SUCCEEDED(hres)) { + hres = IDocHostUIHandler_QueryInterface(This->hostui, &IID_IDocHostUIHandler2, (void **)&handler); + if (SUCCEEDED(hres)) + { hres = IDocHostUIHandler2_GetOverrideKeyPath(handler, pchKey, dw); IDocHostUIHandler2_Release(handler); return hres; @@ -1032,81 +1220,87 @@ static const IDocHostUIHandler2Vtbl DocHostUIHandler2Vtbl = { DocHostUIHandler_GetExternal, DocHostUIHandler_TranslateUrl, DocHostUIHandler_FilterDataObject, - DocHostUIHandler_GetOverrideKeyPath -}; + DocHostUIHandler_GetOverrideKeyPath}; -static inline DocHost *impl_from_IPropertyNotifySink(IPropertyNotifySink *iface) +static inline DocHost * +impl_from_IPropertyNotifySink(IPropertyNotifySink *iface) { return CONTAINING_RECORD(iface, DocHost, IPropertyNotifySink_iface); } -static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, - REFIID riid, void **ppv) +static HRESULT WINAPI +PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, REFIID riid, void **ppv) { DocHost *This = impl_from_IPropertyNotifySink(iface); return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); } -static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface) +static ULONG WINAPI +PropertyNotifySink_AddRef(IPropertyNotifySink *iface) { DocHost *This = impl_from_IPropertyNotifySink(iface); return IOleClientSite_AddRef(&This->IOleClientSite_iface); } -static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface) +static ULONG WINAPI +PropertyNotifySink_Release(IPropertyNotifySink *iface) { DocHost *This = impl_from_IPropertyNotifySink(iface); return IOleClientSite_Release(&This->IOleClientSite_iface); } -static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) +static HRESULT WINAPI +PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) { DocHost *This = impl_from_IPropertyNotifySink(iface); - TRACE("(%p)->(%d)\n", This, dispID); + TRACE("(%p)->(%ld)\n", This, dispID); - switch(dispID) { - case DISPID_READYSTATE: { - READYSTATE ready_state; - HRESULT hres; + switch (dispID) + { + case DISPID_READYSTATE: + { + READYSTATE ready_state; + HRESULT hres; - hres = get_doc_ready_state(This, &ready_state); - if(FAILED(hres)) - return hres; + hres = get_doc_ready_state(This, &ready_state); + if (FAILED(hres)) + return hres; - if(ready_state == READYSTATE_COMPLETE && !This->doc_navigate) - advise_prop_notif(This, FALSE); + if (ready_state == READYSTATE_COMPLETE && !This->doc_navigate) + advise_prop_notif(This, FALSE); - update_ready_state(This, ready_state); - break; - } - default: - FIXME("unimplemented dispid %d\n", dispID); - return E_NOTIMPL; + update_ready_state(This, ready_state); + break; + } + case DISPID_IHTMLDOCUMENT2_TITLE: + fire_titlechange(This); + break; + default: + FIXME("unimplemented dispid %ld\n", dispID); + return E_NOTIMPL; } return S_OK; } -static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) +static HRESULT WINAPI +PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) { DocHost *This = impl_from_IPropertyNotifySink(iface); - FIXME("(%p)->(%d)\n", This, dispID); + FIXME("(%p)->(%ld)\n", This, dispID); return E_NOTIMPL; } static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = { - PropertyNotifySink_QueryInterface, - PropertyNotifySink_AddRef, - PropertyNotifySink_Release, - PropertyNotifySink_OnChanged, - PropertyNotifySink_OnRequestEdit -}; + PropertyNotifySink_QueryInterface, PropertyNotifySink_AddRef, PropertyNotifySink_Release, + PropertyNotifySink_OnChanged, PropertyNotifySink_OnRequestEdit}; -void DocHost_Init(DocHost *This, IWebBrowser2 *wb, const IDocHostContainerVtbl* container) +void +DocHost_Init(DocHost *This, IWebBrowser2 *wb, const IDocHostContainerVtbl *container) { - This->IDocHostUIHandler2_iface.lpVtbl = &DocHostUIHandler2Vtbl; - This->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl; + This->IDocHostUIHandler2_iface.lpVtbl = &DocHostUIHandler2Vtbl; + This->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl; This->IPropertyNotifySink_iface.lpVtbl = &PropertyNotifySinkVtbl; This->wb = wb; @@ -1120,14 +1314,15 @@ void DocHost_Init(DocHost *This, IWebBrowser2 *wb, const IDocHostContainerVtbl* DocHost_ClientSite_Init(This); DocHost_Frame_Init(This); - ConnectionPointContainer_Init(&This->cps, (IUnknown*)wb); + ConnectionPointContainer_Init(&This->cps, (IUnknown *)wb); IEHTMLWindow_Init(This); NewWindowManager_Init(This); } -void DocHost_Release(DocHost *This) +void +DocHost_Release(DocHost *This) { - if(This->shell_ui_helper) + if (This->shell_ui_helper) IShellUIHelper2_Release(This->shell_ui_helper); abort_dochost_tasks(This, NULL); @@ -1136,9 +1331,9 @@ void DocHost_Release(DocHost *This) ConnectionPointContainer_Destroy(&This->cps); - while(This->travellog.length) + while (This->travellog.length) free_travellog_entry(This->travellog.log + --This->travellog.length); - heap_free(This->travellog.log); + free(This->travellog.log); - heap_free(This->url); + free(This->url); } diff --git a/dll/win32/ieframe/ieframe.h b/dll/win32/ieframe/ieframe.h index 4e45918f78f..f71a933f174 100644 --- a/dll/win32/ieframe/ieframe.h +++ b/dll/win32/ieframe/ieframe.h @@ -385,3 +385,13 @@ static inline LPSTR co_strdupWtoA(LPCWSTR str) WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, 0); return ret; } + +enum SessionOp +{ + SESSION_QUERY, + SESSION_INCREMENT, + SESSION_DECREMENT +}; + +LONG WINAPI +SetQueryNetSessionCount(DWORD session_op); diff --git a/dll/win32/ieframe/ieframe.spec b/dll/win32/ieframe/ieframe.spec index 94eb36db9f3..e3fc200b41a 100644 --- a/dll/win32/ieframe/ieframe.spec +++ b/dll/win32/ieframe/ieframe.spec @@ -7,3 +7,4 @@ @ stdcall -private DllUnregisterServer() @ stdcall IEGetWriteableHKCU(ptr) @ stdcall OpenURL(long long str long) +@ stdcall SetQueryNetSessionCount(long) \ No newline at end of file diff --git a/dll/win32/ieframe/ieframe_main.c b/dll/win32/ieframe/ieframe_main.c index b07569e92ec..1911d1eaf5a 100644 --- a/dll/win32/ieframe/ieframe_main.c +++ b/dll/win32/ieframe/ieframe_main.c @@ -306,3 +306,26 @@ HRESULT WINAPI IEGetWriteableHKCU(HKEY *pkey) FIXME("(%p) stub\n", pkey); return E_NOTIMPL; } + +/*********************************************************************** + * SetQueryNetSessionCount (ieframe.@) + */ +LONG WINAPI +SetQueryNetSessionCount(DWORD session_op) +{ + static LONG session_count; + + TRACE("(%lx)\n", session_op); + + switch (session_op) + { + case SESSION_QUERY: + return session_count; + case SESSION_INCREMENT: + return InterlockedIncrement(&session_count); + case SESSION_DECREMENT: + return InterlockedDecrement(&session_count); + }; + + return 0; +} diff --git a/dll/win32/setupapi/CMakeLists.txt b/dll/win32/setupapi/CMakeLists.txt index 55ab2325724..58f45f6e481 100644 --- a/dll/win32/setupapi/CMakeLists.txt +++ b/dll/win32/setupapi/CMakeLists.txt @@ -44,6 +44,6 @@ add_library(setupapi MODULE set_module_type(setupapi win32dll UNICODE) target_link_libraries(setupapi uuid wine ${PSEH_LIB} oldnames) add_delay_importlibs(setupapi comdlg32 shell32 winspool.drv wintrust) -add_importlibs(setupapi gdi32 comctl32 advapi32 user32 rpcrt4 version msvcrt kernel32 ntdll) +add_importlibs(setupapi gdi32 comctl32 advapi32 shell32 user32 rpcrt4 version msvcrt kernel32 ntdll) add_pch(setupapi setupapi_private.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET setupapi DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/setupapi/dialog.c b/dll/win32/setupapi/dialog.c index b1611dc32ba..9d65c7e3565 100644 --- a/dll/win32/setupapi/dialog.c +++ b/dll/win32/setupapi/dialog.c @@ -228,7 +228,7 @@ UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR Disk debugstr_w(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, PathRequiredSize); - if(!FileSought) + if(!FileSought || noBrowse) { SetLastError(ERROR_INVALID_PARAMETER); return DPROMPT_CANCEL; diff --git a/dll/win32/setupapi/driver.c b/dll/win32/setupapi/driver.c index a809303b032..109cfd99c1a 100644 --- a/dll/win32/setupapi/driver.c +++ b/dll/win32/setupapi/driver.c @@ -1852,6 +1852,60 @@ done: return ret; } +/*********************************************************************** + * SetupDiGetDriverInstallParamsW (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiGetDriverInstallParamsA( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, + IN PSP_DRVINFO_DATA_A DriverInfoData, + OUT PSP_DRVINSTALL_PARAMS DriverInstallParams) +{ + BOOL ret = FALSE; + + TRACE("(%p %p %p %p)\n", DeviceInfoSet, DeviceInfoData, DriverInfoData, DriverInstallParams); + + if (!DeviceInfoSet || !DriverInfoData || !DriverInstallParams) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) + SetLastError(ERROR_INVALID_HANDLE); + else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_A)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else if (DriverInstallParams->cbSize != sizeof(SP_DRVINSTALL_PARAMS)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + SP_DEVINSTALL_PARAMS_A InstallParams; + + InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_A); + if (SetupDiGetDeviceInstallParamsA(DeviceInfoSet, DeviceInfoData, &InstallParams)) + { + struct DriverInfoElement *driverInfo; + driverInfo = (struct DriverInfoElement *)InstallParams.ClassInstallReserved; + ERR("ret - driverInfo=%p\n",driverInfo); + if (driverInfo == NULL) + SetLastError(ERROR_NO_DRIVER_SELECTED); + else + { + ERR("ret - driverInfo->Params=0x%X DriverInstallParams->cbSize=%d\n",driverInfo->Params,DriverInstallParams->cbSize); + memcpy( + DriverInstallParams, + &driverInfo->Params, + DriverInstallParams->cbSize); + ret = TRUE; + } + } + } + + TRACE("SetupDiGetDeviceInstallParamsA - Returning %d\n", ret); + return ret; +} + /*********************************************************************** * SetupDiGetDriverInstallParamsW (SETUPAPI.@) */ diff --git a/dll/win32/setupapi/query.c b/dll/win32/setupapi/query.c index b4d1b0c162d..c79aaad49a0 100644 --- a/dll/win32/setupapi/query.c +++ b/dll/win32/setupapi/query.c @@ -32,8 +32,7 @@ static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWOR { LPCWSTR filename = PARSER_get_inf_filename(inf); DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData) - + (lstrlenW(filename) + 1) * sizeof(WCHAR); - + + (lstrlenW(filename) + 1) * sizeof(WCHAR); if (required) *required = total_size; /* FIXME: we need to parse the INF file to find the correct version info */ @@ -711,3 +710,375 @@ BOOL WINAPI SetupQueryInfVersionInformationW(SP_INF_INFORMATION *info, UINT inde SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } + +/*********************************************************************** + * pSetupGetRealSystemTime (SETUPAPI.@) + */ +VOID WINAPI pSetupGetRealSystemTime(_Out_ LPSYSTEMTIME lpRealSystemTime) +{ + GetSystemTime(lpRealSystemTime); +} + +/*********************************************************************** + * SetupFreeSourceListA (SETUPAPI.@) + */ +BOOL WINAPI +SetupFreeSourceListA(PCSTR **List, UINT Count) +{ + TRACE("(%p, %d)\n", List, Count); + for (int i = 0; i < Count; i++) + { + if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(*(List[i])))) + return FALSE; + } + if (!HeapFree(GetProcessHeap(), 0, (LPVOID)*List)) + return FALSE; + *List = NULL; + return TRUE; +} +/*********************************************************************** + * SetupFreeSourceListW (SETUPAPI.@) + */ +BOOL WINAPI +SetupFreeSourceListW(PCWSTR **List, UINT Count) +{ + TRACE("(%p, %d)\n", List, Count); + for (int i = 0; i < Count; i++) + { + if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(*(List[i])))) + return FALSE; + } + if (!HeapFree(GetProcessHeap(), 0, (LPVOID)*List)) + return FALSE; + *List = NULL; + return TRUE; +} +/*********************************************************************** + * SetupQuerySourceListW (SETUPAPI.@) + */ +BOOL WINAPI +SetupQuerySourceListW(DWORD Flags, PCWSTR **List, PUINT Count) +{ + TRACE("(%X, %p, %d)\n", Flags, List, Count); + WCHAR buffer[MAX_PATH * 2] = {0}; + PWSTR szInstallationSource = buffer; + PWSTR *listSources = NULL; + UINT iCount = 0; + if (srclist_temporary_sources != NULL) + { + iCount = srclist_temporary_sources_count; + for (int i = 0; i < srclist_temporary_sources_count; i++) + { + wcscpy(szInstallationSource, srclist_temporary_sources[i]); + szInstallationSource += wcslen(szInstallationSource) + 1; + } + } + else + { + LSTATUS statusUser = 0, statusSystem = 0; + HKEY handle; + DWORD len = 0, nRead = 0; + if (Flags & SRCLIST_SYSTEM || Flags == 0) + { + statusSystem = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_QUERY_VALUE, + &handle); + if (!statusSystem) + { + statusSystem = + RegQueryValueExW(handle, L"Installation Sources", 0, NULL, (LPBYTE)szInstallationSource, &len); + RegCloseKey(handle); + } + if (statusSystem) + { + SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szInstallationSource); + len = wcslen(szInstallationSource); + } + nRead = 0; + while (*szInstallationSource && nRead < len) + { + nRead += wcslen(szInstallationSource) + 1; + szInstallationSource += wcslen(szInstallationSource) + 1; + iCount++; + } + } + if (Flags & SRCLIST_USER || Flags == 0) + { + statusUser = RegOpenKeyExW( + HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_QUERY_VALUE, &handle); + if (!statusUser) + { + statusUser = + RegQueryValueExW(handle, L"Installation Sources", 0, NULL, (LPBYTE)szInstallationSource, &len); + RegCloseKey(handle); + } + if (statusUser && !statusSystem) + { + SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szInstallationSource); + len = wcslen(szInstallationSource); + } + nRead = 0; + while (*szInstallationSource && nRead < len) + { + nRead += wcslen(szInstallationSource) + 1; + szInstallationSource += wcslen(szInstallationSource) + 1; + iCount++; + } + } + } + if (!(Flags & SRCLIST_NOSTRIPPLATFORM)) + { + szInstallationSource = buffer; + for (int i = 0; i < iCount; i++) + { + PWSTR platformSource = wcsstr(szInstallationSource, L"\\x"); + if (platformSource && (platformSource[4] == L'\\' || platformSource[4] == 0) && + ((platformSource[2] == L'8' && platformSource[3] == L'6') || + (platformSource[2] == L'6' && platformSource[3] == L'4'))) + memcpy(platformSource, &platformSource[4], platformSource - szInstallationSource - 4 * sizeof(WCHAR)); + szInstallationSource += wcslen(szInstallationSource) + 1; + } + } + listSources = HeapAlloc(GetProcessHeap(), 0, iCount * sizeof(PWSTR)); + if (!listSources) + return FALSE; + szInstallationSource = buffer; + for (int i = 0; i < iCount; i++) + { + listSources[i] = HeapAlloc(GetProcessHeap(), 0, (wcslen(szInstallationSource) + 1) * sizeof(WCHAR)); + if (!listSources[i]) + { + SetupFreeSourceListW(&listSources, i); + return FALSE; + } + wcscpy(listSources[i], szInstallationSource); + szInstallationSource += wcslen(szInstallationSource) + 1; + } + *List = listSources; + *Count = iCount; + return TRUE; +} +/*********************************************************************** + * SetupQuerySourceListA (SETUPAPI.@) + */ +BOOL WINAPI +SetupQuerySourceListA(DWORD Flags, PCSTR **List, PUINT Count) +{ + TRACE("(%X, %p, %d)\n", Flags, List, Count); + CHAR buffer[MAX_PATH * 2] = {0}; // FIXME - how much...? + PSTR szInstallationSource = buffer; + PSTR *listSources = NULL; + UINT iCount = 0; + if (srclist_temporary_sources != NULL) + { + iCount = srclist_temporary_sources_count; + for (int i = 0; i < srclist_temporary_sources_count; i++) + { + // WideCharToMultiByte(CP_ACP,0,srclist_temporary_sources[i],wcslen(srclist_temporary_sources[i])+1,szInstallationSource,wcslen(srclist_temporary_sources[i])+1,NULL,NULL); + strcpy(szInstallationSource, (PSTR)srclist_temporary_sources[i]); + szInstallationSource += strlen(szInstallationSource) + 1; + } + } + else + { + LSTATUS statusUser = 0, statusSystem = 0; + HKEY handle; + DWORD len = 0, nRead = 0; + if (Flags & SRCLIST_SYSTEM || Flags == 0) + { + statusSystem = RegOpenKeyExA( + HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_QUERY_VALUE, &handle); + if (!statusSystem) + { + statusSystem = + RegQueryValueExA(handle, "Installation Sources", 0, NULL, (LPBYTE)szInstallationSource, &len); + RegCloseKey(handle); + } + if (statusSystem) + { + SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szInstallationSource); + len = strlen(szInstallationSource); + } + nRead = 0; + while (*szInstallationSource && nRead < len) + { + nRead += strlen(szInstallationSource) + 1; + szInstallationSource += strlen(szInstallationSource) + 1; + iCount++; + } + } + if (Flags & SRCLIST_USER || Flags == 0) + { + statusUser = RegOpenKeyExA( + HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_QUERY_VALUE, &handle); + if (!statusUser) + { + statusUser = + RegQueryValueExA(handle, "Installation Sources", 0, NULL, (LPBYTE)szInstallationSource, &len); + RegCloseKey(handle); + } + if (statusUser && !statusSystem) + { + SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szInstallationSource); + len = strlen(szInstallationSource); + } + nRead = 0; + while (*szInstallationSource && nRead < len) + { + nRead += strlen(szInstallationSource) + 1; + szInstallationSource += strlen(szInstallationSource) + 1; + iCount++; + } + } + } + if (!(Flags & SRCLIST_NOSTRIPPLATFORM)) + { + szInstallationSource = buffer; + for (int i = 0; i < iCount; i++) + { + PSTR platformSource = strstr(szInstallationSource, "\\x"); + if (platformSource && (platformSource[4] == '\\' || platformSource[4] == 0) && + ((platformSource[2] == '8' && platformSource[3] == '6') || + (platformSource[2] == '6' && platformSource[3] == '4'))) + memcpy(platformSource, &platformSource[4], platformSource - szInstallationSource - 4 * sizeof(WCHAR)); + szInstallationSource += strlen(szInstallationSource) + 1; + } + } + listSources = HeapAlloc(GetProcessHeap(), 0, iCount * sizeof(PSTR)); + if (!listSources) + return FALSE; + szInstallationSource = buffer; + for (int i = 0; i < iCount; i++) + { + listSources[i] = HeapAlloc(GetProcessHeap(), 0, (strlen(szInstallationSource) + 1) * sizeof(CHAR)); + if (!listSources[i]) + { + SetupFreeSourceListA(&listSources, i); + return FALSE; + } + strcpy(listSources[i], szInstallationSource); + szInstallationSource += strlen(szInstallationSource) + 1; + } + *List = listSources; + *Count = iCount; + return TRUE; +} +/*********************************************************************** + * SetupCancelTemporarySourceList (SETUPAPI.@) + */ +BOOL WINAPI +SetupCancelTemporarySourceList() +{ + if (srclist_temporary_sources == NULL) + return FALSE; + srclist_temporary_sources = NULL; + srclist_temporary_sources_count = 0; + noBrowse = FALSE; + return TRUE; +} +/*********************************************************************** + * SetupSetSourceListA (SETUPAPI.@) + */ +BOOL WINAPI +SetupSetSourceListA(DWORD flags, PCSTR *list, UINT count) +{ + TRACE("(%X, %p, %d)\n", flags, list, count); + if (flags & SRCLIST_TEMPORARY) + { + srclist_temporary_sources = (PVOID *)*list; + srclist_temporary_sources_count = count; + } + else + { + HKEY handle; + LSTATUS status = 0; + UINT len = 0; + BYTE buffer[MAX_PATH]; // size? + BYTE *currentPos = NULL; + currentPos = buffer; + for (int i = 0; i < count; i++) + { + strcpy(currentPos, list[i]); + currentPos += strlen(list[i]) + 1; + } + len = currentPos - buffer; + if (flags & SRCLIST_SYSTEM) + { + status = RegOpenKeyExA( + HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_SET_VALUE, &handle); + if (status) + return FALSE; + status = RegSetValueExA(handle, "Installation Sources", 0, REG_MULTI_SZ, buffer, len); + if (status) + return FALSE; + RegCloseKey(handle); + } + if (flags & SRCLIST_USER) + { + status = RegOpenKeyExA( + HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_SET_VALUE, &handle); + if (status) + return FALSE; + status = RegSetValueExA(handle, "Installation Sources", 0, REG_MULTI_SZ, buffer, len); + RegCloseKey(handle); + if (status) + return FALSE; + } + } + if (flags & SRCLIST_NOBROWSE) + noBrowse = TRUE; + return TRUE; +} +/*********************************************************************** + * SetupSetSourceListW (SETUPAPI.@) + */ +BOOL WINAPI +SetupSetSourceListW(DWORD flags, PCWSTR *list, UINT count) +{ + TRACE("(%X, %p, %d)\n", flags, list, count); + if (flags & SRCLIST_TEMPORARY) + { + srclist_temporary_sources = (PVOID *)*list; + srclist_temporary_sources_count = count; + } + else + { + HKEY handle = NULL; + LSTATUS status = 0; + UINT len = 0; + BYTE buffer[MAX_PATH]; + BYTE *currentPos = NULL; + currentPos = buffer; + for (int i = 0; i < count; i++) + { + wcscpy((wchar_t *)currentPos, list[i]); + currentPos += wcslen(list[i]) + 1; + } + len = currentPos - buffer; + if (flags & SRCLIST_SYSTEM) + { + status = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_SET_VALUE, &handle); + if (status) + return FALSE; + status = RegSetValueExW(handle, L"Installation Sources", 0, REG_MULTI_SZ, buffer, len); + if (status) + return FALSE; + RegCloseKey(handle); + } + if (flags & SRCLIST_USER) + { + status = RegOpenKeyExW( + HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", 0, KEY_SET_VALUE, &handle); + if (status) + return FALSE; + status = RegSetValueExW(handle, L"Installation Sources", 0, REG_MULTI_SZ, buffer, len); + RegCloseKey(handle); + if (status) + return FALSE; + } + } + if (flags & SRCLIST_NOBROWSE) + noBrowse = TRUE; + return TRUE; +} diff --git a/dll/win32/setupapi/setupapi.spec b/dll/win32/setupapi/setupapi.spec index 19a4aaac934..6ecfe404c52 100644 --- a/dll/win32/setupapi/setupapi.spec +++ b/dll/win32/setupapi/setupapi.spec @@ -259,7 +259,7 @@ @ stub SetupAdjustDiskSpaceListW @ stub SetupBackupErrorA @ stub SetupBackupErrorW -@ stub SetupCancelTemporarySourceList +@ stdcall SetupCancelTemporarySourceList() @ stdcall SetupCloseFileQueue(ptr) @ stdcall SetupCloseInfFile(long) @ stdcall SetupCloseLog() @@ -371,7 +371,7 @@ @ stdcall SetupDiGetDeviceRegistryPropertyW(long ptr long ptr ptr long ptr) @ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr) @ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr) -@ stub SetupDiGetDriverInstallParamsA +@ stdcall SetupDiGetDriverInstallParamsA(ptr ptr ptr ptr) @ stdcall SetupDiGetDriverInstallParamsW(ptr ptr ptr ptr) @ stub SetupDiGetHwProfileFriendlyNameA @ stub SetupDiGetHwProfileFriendlyNameExA @@ -448,8 +448,8 @@ @ stdcall SetupFindNextLine(ptr ptr) @ stdcall SetupFindNextMatchLineA(ptr str ptr) @ stdcall SetupFindNextMatchLineW(ptr wstr ptr) -@ stub SetupFreeSourceListA -@ stub SetupFreeSourceListW +@ stdcall SetupFreeSourceListA(ptr long) +@ stdcall SetupFreeSourceListW(ptr long) @ stub SetupGetBackupInformationA @ stub SetupGetBackupInformationW @ stdcall SetupGetBinaryField(ptr long ptr long ptr) @@ -536,8 +536,8 @@ @ stdcall SetupQueryInfOriginalFileInformationW(ptr long ptr ptr) @ stdcall SetupQueryInfVersionInformationA(ptr long str ptr long ptr) @ stdcall SetupQueryInfVersionInformationW(ptr long wstr ptr long ptr) -@ stub SetupQuerySourceListA -@ stub SetupQuerySourceListW +@ stdcall SetupQuerySourceListA(long ptr ptr) +@ stdcall SetupQuerySourceListW(long ptr ptr) @ stdcall SetupQuerySpaceRequiredOnDriveA(long str ptr ptr long) @ stdcall SetupQuerySpaceRequiredOnDriveW(long wstr ptr ptr long) @ stdcall SetupQueueCopyA(long str str str str str str str long) @@ -634,7 +634,7 @@ @ stub -version=0x600+ pSetupGetIndirectStringsFromDriverInfo @ stub pSetupGetInfSections @ stdcall pSetupGetQueueFlags(ptr) -@ stub pSetupGetRealSystemTime +@ stdcall pSetupGetRealSystemTime(ptr) @ stdcall -version=0x501-0x502 pSetupGetVersionInfoFromImage(wstr ptr ptr) @ stdcall pSetupGuidFromString(wstr ptr) @ stub pSetupHandleFailedVerification diff --git a/dll/win32/setupapi/setupapi_private.h b/dll/win32/setupapi/setupapi_private.h index 7a11aa680ba..882ee355b78 100644 --- a/dll/win32/setupapi/setupapi_private.h +++ b/dll/win32/setupapi/setupapi_private.h @@ -383,4 +383,9 @@ LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage); typedef BOOL (*FIND_CALLBACK)(LPCWSTR SectionName, PVOID Context); BOOL EnumerateSectionsStartingWith(HINF hInf, LPCWSTR pStr, FIND_CALLBACK Callback, PVOID Context); +PVOID* srclist_temporary_sources; +UINT srclist_temporary_sources_count; +static BOOLEAN noBrowse = FALSE; + + #endif /* __SETUPAPI_PRIVATE_H */ diff --git a/dll/win32/setupapi/stubs.c b/dll/win32/setupapi/stubs.c index 17ded50eeb3..520420d6320 100644 --- a/dll/win32/setupapi/stubs.c +++ b/dll/win32/setupapi/stubs.c @@ -56,25 +56,6 @@ BOOL WINAPI SetupAddToSourceListW(DWORD flags, PCWSTR source) return TRUE; } -/*********************************************************************** - * SetupSetSourceListA (SETUPAPI.@) - */ -BOOL WINAPI SetupSetSourceListA(DWORD flags, PCSTR *list, UINT count) -{ - FIXME("0x%08x %p %d\n", flags, list, count); - return FALSE; -} - -/*********************************************************************** - * SetupSetSourceListW (SETUPAPI.@) - */ -BOOL WINAPI SetupSetSourceListW(DWORD flags, PCWSTR *list, UINT count) -{ - FIXME("0x%08x %p %d\n", flags, list, count); - return FALSE; -} - - /*********************************************************************** * SetupDiRemoveDevice(SETUPAPI.@) */ diff --git a/dll/win32/shdocvw/shdocvw.spec b/dll/win32/shdocvw/shdocvw.spec index 22f99fa9dda..290f45dee8d 100644 --- a/dll/win32/shdocvw/shdocvw.spec +++ b/dll/win32/shdocvw/shdocvw.spec @@ -125,4 +125,4 @@ 231 stub -noname RecordExtensionCreation 232 stub -noname GetExtensionRecords 233 stub -noname GetExtensionRecordBlockReason -234 stub -noname ClearExtensionRecordsBlockReason +234 stdcall -stub ClearExtensionRecordsBlockReason() \ No newline at end of file diff --git a/drivers/bus/acpi/interface.c b/drivers/bus/acpi/interface.c index 817f56095b1..d6fcd1c20c9 100644 --- a/drivers/bus/acpi/interface.c +++ b/drivers/bus/acpi/interface.c @@ -104,16 +104,17 @@ Bus_PDO_QueryInterface(PPDO_DEVICE_DATA DeviceData, return STATUS_INVALID_PARAMETER; } - if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType, - &GUID_ACPI_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID)) + if (1 /* RtlCompareMemory( + IrpSp->Parameters.QueryInterface.InterfaceType, + &GUID_ACPI_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID)*/) { DPRINT("GUID_ACPI_INTERFACE_STANDARD\n"); - if (IrpSp->Parameters.QueryInterface.Size < sizeof(ACPI_INTERFACE_STANDARD)) + /* if (IrpSp->Parameters.QueryInterface.Size < sizeof(ACPI_INTERFACE_STANDARD)) { DPRINT1("Buffer too small! (%d)\n", IrpSp->Parameters.QueryInterface.Size); return STATUS_BUFFER_TOO_SMALL; - } + }*/ AcpiInterface = (PACPI_INTERFACE_STANDARD)IrpSp->Parameters.QueryInterface.Interface; diff --git a/hal/halx86/acpi/halacpi.c b/hal/halx86/acpi/halacpi.c index 090b862d7a0..2fb91317eba 100644 --- a/hal/halx86/acpi/halacpi.c +++ b/hal/halx86/acpi/halacpi.c @@ -44,6 +44,8 @@ BOOLEAN HalDisableFirmwareMapper = TRUE; PWCHAR HalHardwareIdString = L"acpipic_up"; PWCHAR HalName = L"ACPI Compatible Eisa/Isa HAL"; +BOOLEAN isHyperV = FALSE; + /* PRIVATE FUNCTIONS **********************************************************/ PDESCRIPTION_HEADER @@ -786,6 +788,37 @@ HaliAcpiTimerInit(IN ULONG TimerPort, //HalaAcpiTimerInit(TimerPort, TimerValExt); } +/** + * @brief + * This checks if running on Hyper-V + **/ +BOOLEAN HalpIsHyperV(VOID) +{ + INT CpuInfo[4]; + ULONG MaxHvLeaf; + + /* Check if we are running under a hypervisor */ + __cpuid(CpuInfo, 1); + if (!(CpuInfo[2] & 0x80000000)) + return FALSE; + + /* Check for the Hyper-V signature "Microsoft Hv" */ + __cpuid(CpuInfo, 0x40000000); + MaxHvLeaf = (ULONG)CpuInfo[0]; + DPRINT1( + "Hypervisor CPUID: max leaf 0x%lx, signature '%.4s%.4s%.4s'\n", MaxHvLeaf, (PCHAR)&CpuInfo[1], + (PCHAR)&CpuInfo[2], (PCHAR)&CpuInfo[3]); + if (CpuInfo[1] != 0x7263694D || /* "Micr" */ + CpuInfo[2] != 0x666F736F || /* "osof" */ + CpuInfo[3] != 0x76482074) /* "t Hv" */ + return FALSE; + + if (MaxHvLeaf < 0x40000002) + return FALSE; + + return TRUE; +} + CODE_SEG("INIT") NTSTATUS NTAPI @@ -799,6 +832,8 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Only do this once */ if (HalpProcessedACPIPhase0) return STATUS_SUCCESS; + + /* Setup the ACPI table cache */ Status = HalpAcpiTableCacheInit(LoaderBlock); if (!NT_SUCCESS(Status)) return Status; @@ -888,8 +923,15 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) case 1: AcpiVersion = "1.0-1.0b"; break; - case 2: // Should not happen. - AcpiVersion = "Unknown_2"; + case 2: + isHyperV = HalpIsHyperV(); + if (isHyperV) + { + AcpiVersion = "1.0b MS Extension"; + __writemsr(0x40000021,0); + } + else // Should not happen. + AcpiVersion = "Unknown_2"; break; case 3: AcpiVersion = "1.5-2.0_C"; diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index 0ec72d5d949..edb25ee06e8 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -26,6 +26,7 @@ ULONG ApicVersion; UCHAR HalpVectorToIndex[256]; +extern BOOLEAN isHyperV; #ifndef _M_AMD64 const UCHAR @@ -87,6 +88,7 @@ HalVectorToIRQL[16] = }; #endif + /* PRIVATE FUNCTIONS **********************************************************/ FORCEINLINE @@ -165,12 +167,17 @@ ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode) /* Wait for the APIC to be idle */ do { - IcrStatus.Long0 = ApicRead(APIC_ICR0); + IcrStatus.Long0 = isHyperV ? __readmsr(HV_X64_MSR_ICR) : ApicRead(APIC_ICR0); } while (IcrStatus.DeliveryStatus); /* Write high dword first, then low dword to send the interrupt */ - ApicWrite(APIC_ICR1, Icr.Long1); - ApicWrite(APIC_ICR0, Icr.Long0); + if (isHyperV) + __writemsr(HV_X64_MSR_ICR, Icr.LongLong); + else + { + ApicWrite(APIC_ICR1, Icr.Long1); + ApicWrite(APIC_ICR0, Icr.Long0); + } /* Wait until we see the interrupt request. * It will stay in requested state until we re-enable interrupts. @@ -191,7 +198,10 @@ FORCEINLINE VOID ApicSendEOI(void) { - ApicWrite(APIC_EOI, 0); + if (isHyperV) + __writemsr(HV_X64_MSR_EOI, 0); + else + ApicWrite(APIC_EOI, 0); } FORCEINLINE @@ -246,7 +256,7 @@ ApicLowerIrql(KIRQL Irql) KeGetPcr()->IRR = Irql; /* Need to lower it back */ - ApicWrite(APIC_TPR, IrqlToTpr(Irql)); + ApicSetIrql(Irql); } } #else @@ -503,8 +513,9 @@ ApicInitializeIOApic(VOID) ReDirReg.Vector = APIC_CLOCK_VECTOR; ReDirReg.MessageType = APIC_MT_Fixed; ReDirReg.DestinationMode = APIC_DM_Physical; - ReDirReg.TriggerMode = APIC_TGM_Level; - ReDirReg.Mask = 1; + ReDirReg.TriggerMode = APIC_TGM_Edge; + ReDirReg.Mask = 0; + ReDirReg.Polarity = 0; ReDirReg.Destination = ApicRead(APIC_ID) >> 24; ApicWriteIORedirectionEntry(APIC_CLOCK_INDEX, ReDirReg); } diff --git a/hal/halx86/apic/apicp.h b/hal/halx86/apic/apicp.h index 86809a2c98f..da56e1938c5 100644 --- a/hal/halx86/apic/apicp.h +++ b/hal/halx86/apic/apicp.h @@ -62,6 +62,10 @@ #define APIC_FREE_VECTOR 0xFF #define APIC_RESERVED_VECTOR 0xFE +#define HV_X64_MSR_TSC_FREQUENCY 0x40000022 +#define HV_X64_MSR_ICR 0x40000071 +#define HV_X64_MSR_EOI 0x40000070 + /* The IMCR is supported by two read/writable or write-only I/O ports, 22h and 23h, which receive address and data respectively. To access the IMCR, write a value of 70h to I/O port 22h, which selects the IMCR. @@ -327,10 +331,6 @@ ApicWrite(APIC_REGISTER Register, ULONG Value) WRITE_REGISTER_ULONG((PULONG)(APIC_BASE + Register), Value); } -VOID -NTAPI -ApicInitializeTimer(ULONG Cpu); - VOID NTAPI HalInitializeProfiling(VOID); @@ -340,3 +340,5 @@ NTAPI HalpInitApicInfo(IN PLOADER_PARAMETER_BLOCK KeLoaderBlock); VOID __cdecl ApicSpuriousService(VOID); + +BOOLEAN HalpIsHyperV(VOID); diff --git a/hal/halx86/apic/apicsmp.c b/hal/halx86/apic/apicsmp.c index 5165a367156..297e3a72407 100644 --- a/hal/halx86/apic/apicsmp.c +++ b/hal/halx86/apic/apicsmp.c @@ -16,6 +16,7 @@ #include +extern BOOLEAN isHyperV; extern PPROCESSOR_IDENTITY HalpProcessorIdentity; /* INTERNAL FUNCTIONS *********************************************************/ @@ -77,7 +78,7 @@ ApicRequestGlobalInterrupt( /* Wait for the APIC to be idle */ do { - Icr.Long0 = ApicRead(APIC_ICR0); + Icr.Long0 = isHyperV ? __readmsr(HV_X64_MSR_ICR) : ApicRead(APIC_ICR0); } while (Icr.DeliveryStatus); /* Setup the command register */ @@ -93,8 +94,13 @@ ApicRequestGlobalInterrupt( Icr.Destination = DestinationProcessor; /* Write the low dword last to send the interrupt */ - ApicWrite(APIC_ICR1, Icr.Long1); - ApicWrite(APIC_ICR0, Icr.Long0); + if (isHyperV) + __writemsr(HV_X64_MSR_ICR, Icr.LongLong); + else + { + ApicWrite(APIC_ICR1, Icr.Long1); + ApicWrite(APIC_ICR0, Icr.Long0); + } /* Finally, restore the original interrupt state */ if (Flags & EFLAGS_INTERRUPT_MASK) diff --git a/hal/halx86/apic/apictimer.c b/hal/halx86/apic/apictimer.c index 9052655da43..84783ff8efe 100644 --- a/hal/halx86/apic/apictimer.c +++ b/hal/halx86/apic/apictimer.c @@ -45,22 +45,6 @@ ApicSetTimerInterval(ULONG MicroSeconds) } -VOID -NTAPI -ApicInitializeTimer(ULONG Cpu) -{ - - /* Initialize the TSC */ - //HalpInitializeTsc(); - - /* Set clock multiplier to 1 */ - ApicWrite(APIC_TDCR, TIMER_DV_DivideBy1); - - ApicSetTimerInterval(1000); - -// KeSetTimeIncrement -} - VOID FASTCALL HalpProfileInterruptHandler(_In_ PKTRAP_FRAME TrapFrame) diff --git a/hal/halx86/apic/halinit.c b/hal/halx86/apic/halinit.c index b313b595acc..543f0dceada 100644 --- a/hal/halx86/apic/halinit.c +++ b/hal/halx86/apic/halinit.c @@ -37,9 +37,6 @@ HalpInitProcessor( /* Initialize profiling data (but don't start it) */ HalInitializeProfiling(); - - /* Initialize the timer */ - //ApicInitializeTimer(ProcessorNumber); } VOID diff --git a/hal/halx86/apic/tsc.c b/hal/halx86/apic/tsc.c index 2de7406097a..2566a19edb9 100644 --- a/hal/halx86/apic/tsc.c +++ b/hal/halx86/apic/tsc.c @@ -14,6 +14,7 @@ #define NDEBUG #include +extern BOOLEAN isHyperV; LARGE_INTEGER HalpCpuClockFrequency = {{INITIAL_STALL_COUNT * 1000000}}; UCHAR TscCalibrationPhase; @@ -58,6 +59,12 @@ HalpInitializeTsc(VOID) PVOID PreviousHandler; UCHAR RegisterA, RegisterB; + if (isHyperV) + { + HalpCpuClockFrequency.QuadPart = __readmsr(HV_X64_MSR_TSC_FREQUENCY); + return; + } + /* Check if the CPU supports RDTSC */ if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC)) { @@ -68,6 +75,9 @@ HalpInitializeTsc(VOID) Flags = __readeflags(); _disable(); + /* Acquire CMOS lock */ + HalpAcquireCmosSpinLock(); + /* Enable the periodic interrupt in the CMOS */ RegisterB = HalpReadCmos(RTC_REGISTER_B); HalpWriteCmos(RTC_REGISTER_B, RegisterB | RTC_REG_B_PI); @@ -100,6 +110,9 @@ HalpInitializeTsc(VOID) /* Disable the periodic interrupt in the CMOS */ HalpWriteCmos(RTC_REGISTER_B, RegisterB & ~RTC_REG_B_PI); + /* Release CMOS lock */ + HalpReleaseCmosSpinLock(); + /* Disable the timer interrupt */ HalDisableSystemInterrupt(APIC_CLOCK_VECTOR, CLOCK_LEVEL); @@ -107,12 +120,11 @@ HalpInitializeTsc(VOID) KeRegisterInterruptHandler(APIC_CLOCK_VECTOR, PreviousHandler); /* Calculate an average, using simplified linear regression */ - HalpCpuClockFrequency.QuadPart = DoLinearRegression(NUM_SAMPLES - 1, - TscCalibrationArray); + HalpCpuClockFrequency.QuadPart = DoLinearRegression(NUM_SAMPLES - 1, TscCalibrationArray); + /* Restore flags */ __writeeflags(Flags); - } CODE_SEG("INIT") diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S index 7b07b333e73..1353466a6b3 100644 --- a/ntoskrnl/ke/amd64/trap.S +++ b/ntoskrnl/ke/amd64/trap.S @@ -11,6 +11,8 @@ #include #include +HV_X64_MSR_EOI EQU HEX(40000070) + EXTERN KiDispatchException:PROC EXTERN KeBugCheckWithTf:PROC EXTERN MmAccessFault:PROC @@ -608,7 +610,10 @@ PUBLIC KiApcInterrupt mov cr8, rax /* End the interrupt */ - mov dword ptr [APIC_EOI], 0 + mov ECX, HV_X64_MSR_EOI + xor eax, eax + xor edx, edx + wrmsr /* Enable interrupts */ sti @@ -690,7 +695,10 @@ PUBLIC KiIpiInterrupt mov cr8, rax /* End the interrupt */ - mov dword ptr [APIC_EOI], 0 + mov ECX,HV_X64_MSR_EOI + xor eax, eax + xor edx, edx + wrmsr int 3 diff --git a/sdk/include/asm/trapamd64.inc b/sdk/include/asm/trapamd64.inc index 04a1515388b..06fe1dfcfa2 100644 --- a/sdk/include/asm/trapamd64.inc +++ b/sdk/include/asm/trapamd64.inc @@ -5,6 +5,8 @@ * COPYRIGHT: Copyright 2011-2024 Timo Kreuzer (timo.kreuzer@reactos.org) */ + HV_X64_MSR_EOI EQU HEX(40000070) + MACRO(ASSERT_TRAP_FRAME_INTS_ENABLED, Register) #if DBG LOCAL IntsAreEnabled @@ -253,7 +255,10 @@ kernel_mode_return: if (Flags AND TF_SEND_EOI) /* Write 0 to the local APIC EOI register */ - mov dword ptr [APIC_EOI], 0 + mov ECX, HV_X64_MSR_EOI + xor eax, eax + xor edx, edx + wrmsr endif /* Return from the trap */ diff --git a/win32ss/user/ntuser/defwnd.c b/win32ss/user/ntuser/defwnd.c index 092b32d6e6d..3054a62dc9e 100644 --- a/win32ss/user/ntuser/defwnd.c +++ b/win32ss/user/ntuser/defwnd.c @@ -461,7 +461,7 @@ DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam) UserSetProp(pWnd, gpsi->atomIconProp, hIcon, TRUE); UserSetProp(pWnd, gpsi->atomIconSmProp, hIconSmall, TRUE); - if ((pWnd->style & WS_CAPTION ) == WS_CAPTION) + if ((pWnd->style & WS_CAPTION) == WS_CAPTION) UserPaintCaption(pWnd, DC_ICON); return (LRESULT)hIconOld;