From eba0559676318f73f578d164c9e0877bee708976 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Thu, 30 Apr 2009 22:00:40 +0200 Subject: [PATCH] push 22b3e00525a9a3743634eb8f21ffe1bf98bf885e --- dlls/clusapi/clusapi.c | 2 +- dlls/clusapi/clusapi.spec | 2 +- dlls/comctl32/commctrl.c | 2 +- dlls/comctl32/header.c | 3 +- dlls/comctl32/listview.c | 167 +++++- dlls/comctl32/tests/listview.c | 92 +++ dlls/cryptui/main.c | 16 +- dlls/d3d10core/d3d10core_private.h | 5 + dlls/d3d10core/device.c | 21 +- dlls/d3d10core/shader.c | 31 + dlls/d3d8/d3d8_private.h | 2 + dlls/d3d8/device.c | 13 + dlls/d3d8/directx.c | 1 + dlls/d3d9/d3d9_private.h | 2 + dlls/d3d9/directx.c | 2 + dlls/d3d9/tests/visual.c | 2 +- dlls/d3d9/vertexshader.c | 12 + dlls/gdi32/freetype.c | 16 +- dlls/gdi32/tests/bitmap.c | 35 +- dlls/gdi32/tests/dc.c | 76 +++ dlls/gdi32/tests/font.c | 4 +- dlls/gdiplus/brush.c | 113 +++- dlls/gdiplus/font.c | 6 +- dlls/gdiplus/gdiplus.spec | 6 +- dlls/gdiplus/gdiplus_private.h | 4 + dlls/gdiplus/graphics.c | 12 +- dlls/gdiplus/image.c | 15 + dlls/gdiplus/tests/brush.c | 108 ++++ dlls/gdiplus/tests/font.c | 14 + dlls/inetmib1/tests/main.c | 5 +- dlls/iphlpapi/ifenum.c | 4 +- dlls/iphlpapi/ifenum.h | 3 + dlls/iphlpapi/iphlpapi.spec | 1 + dlls/iphlpapi/iphlpapi_main.c | 173 ++++++ dlls/iphlpapi/tests/iphlpapi.c | 69 +++ dlls/kernel32/editline.c | 40 +- dlls/kernel32/tests/heap.c | 38 +- dlls/kernel32/tests/volume.c | 158 ++++- dlls/kernel32/volume.c | 6 +- dlls/mciqtz32/mciqtz.c | 194 +++++- dlls/mciqtz32/mciqtz_private.h | 1 + dlls/mscoree/mscoree.spec | 4 +- dlls/mscoree/mscoree_main.c | 12 + dlls/mshtml/main.c | 1 - dlls/msi/msi.c | 4 +- dlls/msi/sql.y | 6 +- dlls/msi/tests/db.c | 24 +- dlls/msvfw32/tests/msvfw.c | 10 + dlls/ntdll/exception.c | 315 +--------- dlls/ntdll/heap.c | 4 + dlls/ntdll/ntdll_misc.h | 3 +- dlls/ntdll/signal_i386.c | 242 ++++++++ dlls/ntdll/signal_powerpc.c | 101 ++++ dlls/ntdll/signal_sparc.c | 100 ++++ dlls/ntdll/signal_x86_64.c | 127 ++++ dlls/ole32/clipboard.c | 106 +++- dlls/ole32/memlockbytes.c | 2 +- dlls/ole32/rpc.c | 2 +- dlls/ole32/storage32.c | 2 +- dlls/ole32/tests/clipboard.c | 150 +++++ dlls/oleaut32/tmarshal.c | 2 +- dlls/rasapi32/tests/rasapi.c | 2 + dlls/riched20/tests/editor.c | 56 ++ dlls/riched20/writer.c | 4 +- dlls/shell32/pidl.c | 11 + dlls/shell32/shell32.spec | 1 + dlls/urlmon/tests/protocol.c | 4 +- dlls/user32/listbox.c | 25 +- dlls/user32/tests/msg.c | 40 ++ dlls/user32/tests/scroll.c | 128 ++++ dlls/wined3d/arb_program_shader.c | 2 +- dlls/wined3d/baseshader.c | 1082 ++++++++++++++++++++-------------- dlls/wined3d/buffer.c | 16 +- dlls/wined3d/device.c | 45 +- dlls/wined3d/directx.c | 13 +- dlls/wined3d/glsl_shader.c | 143 +++-- dlls/wined3d/pixelshader.c | 192 +++--- dlls/wined3d/state.c | 2 +- dlls/wined3d/surface.c | 40 ++ dlls/wined3d/vertexshader.c | 148 ++--- dlls/wined3d/wined3d_gl.h | 2 +- dlls/wined3d/wined3d_private.h | 15 +- dlls/wined3d/wined3d_private_types.h | 21 +- dlls/winex11.drv/graphics.c | 7 +- dlls/wininet/ftp.c | 16 +- dlls/wininet/http.c | 9 +- dlls/wininet/internet.c | 19 + dlls/wininet/tests/http.c | 9 + dlls/wininet/urlcache.c | 1 + dlls/wininet/wininet.spec | 4 +- dlls/ws2_32/socket.c | 193 +++++- dlls/ws2_32/tests/sock.c | 200 +++++++ dlls/ws2_32/ws2_32.spec | 1 + fonts/tahomabd.sfd | 633 +++++++++++++++++++- fonts/tahomabd.ttf | Bin 76624 -> 80408 bytes include/commctrl.h | 2 +- include/gdiplusflat.h | 3 + include/ipifcons.h | 29 + include/iptypes.h | 135 +++++ include/mshtmdid.h | 29 + include/mshtml.idl | 439 ++++++++++++++ include/shlobj.h | 1 + include/wininet.h | 17 + include/ws2ipdef.h | 16 + include/ws2tcpip.h | 4 +- programs/cmdlgtst/De.rc | 2 +- programs/explorer/desktop.c | 9 + programs/notepad/De.rc | 1 + programs/notepad/En.rc | 1 + programs/notepad/dialog.c | 37 +- programs/notepad/dialog.h | 1 + programs/notepad/main.c | 82 +++ programs/notepad/main.h | 1 + programs/notepad/notepad_res.h | 1 + programs/notepad/rsrc.rc | 1 + programs/services/rpc.c | 2 +- programs/winetest/main.c | 1 + tools/winemaker | 18 +- 118 files changed, 5373 insertions(+), 1236 deletions(-) diff --git a/dlls/clusapi/clusapi.c b/dlls/clusapi/clusapi.c index 243c97903d2..fa90de31ef3 100644 --- a/dlls/clusapi/clusapi.c +++ b/dlls/clusapi/clusapi.c @@ -97,7 +97,7 @@ DWORD WINAPI ClusterCloseEnum(HCLUSENUM hEnum) */ DWORD WINAPI ClusterEnum(HCLUSENUM hEnum, DWORD dwIndex, LPDWORD lpdwType, LPWSTR lpszName, LPDWORD lpcchName) { - FIXME("(%p, %u, %u, %s, %u) stub!\n", hEnum, dwIndex, *lpdwType, debugstr_w(lpszName), *lpcchName); + FIXME("(%p, %u, %u, %p, %u) stub!\n", hEnum, dwIndex, *lpdwType, lpszName, *lpcchName); return ERROR_NO_MORE_ITEMS; } diff --git a/dlls/clusapi/clusapi.spec b/dlls/clusapi/clusapi.spec index 5ad0b2e9436..9c6abe2217f 100644 --- a/dlls/clusapi/clusapi.spec +++ b/dlls/clusapi/clusapi.spec @@ -12,7 +12,7 @@ @ stub CloseClusterResource @ stdcall ClusterCloseEnum(ptr) @ stub ClusterControl -@ stdcall ClusterEnum(ptr long ptr wstr ptr) +@ stdcall ClusterEnum(ptr long ptr ptr ptr) @ stub ClusterGetEnumCount @ stub ClusterGroupCloseEnum @ stub ClusterGroupControl diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 782d9b96129..db0eade682b 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -772,7 +772,7 @@ InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls) HWND WINAPI CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps, - HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons, + HINSTANCE hBMInst, UINT_PTR wBMID, LPCTBBUTTON lpButtons, INT iNumButtons, INT dxButton, INT dyButton, INT dxBitmap, INT dyBitmap, UINT uStructSize) { diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c index f9eba991f2c..7e6e0ff378e 100644 --- a/dlls/comctl32/header.c +++ b/dlls/comctl32/header.c @@ -1663,7 +1663,8 @@ HEADER_LButtonUp (HWND hwnd, LPARAM lParam) } else InvalidateRect(hwnd, &infoPtr->items[infoPtr->iMoveItem].rect, FALSE); - + + infoPtr->bDragging = FALSE; HEADER_SetHotDivider(hwnd, FALSE, -1); } else if (!(dwStyle&HDS_DRAGDROP) || !HEADER_IsDragDistance(infoPtr, &pt)) diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 2aed87e1a34..169c242f41e 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -72,7 +72,6 @@ * Flags * -- LVIF_COLUMNS * -- LVIF_GROUPID - * -- LVIF_NORECOMPUTE * * States * -- LVIS_ACTIVATING (not currently supported by comctl32.dll version 6.0) @@ -309,6 +308,8 @@ typedef struct tagLISTVIEW_INFO INT nMeasureItemHeight; INT xTrackLine; /* The x coefficient of the track line or -1 if none */ DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ + + DWORD iVersion; /* CCM_[G,S]ETVERSION */ } LISTVIEW_INFO; /* @@ -1411,6 +1412,13 @@ static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpL return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE); } +/* used to handle collapse main item column case */ +static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc) +{ + return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ? + DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE; +} + /* Listview invalidation functions: use _only_ these functions to invalidate */ static inline BOOL is_redrawing(const LISTVIEW_INFO *infoPtr) @@ -1861,7 +1869,7 @@ static void LISTVIEW_ShowFocusRect(const LISTVIEW_INFO *infoPtr, BOOL fShow) } else { - DrawFocusRect(hdc, &infoPtr->rcFocus); + LISTVIEW_DrawFocusRect(infoPtr, hdc); } done: ReleaseDC(infoPtr->hwndSelf, hdc); @@ -4148,10 +4156,11 @@ static void LISTVIEW_RefreshReportGrid(LISTVIEW_INFO *infoPtr, HDC hdc) INT rgntype; INT y, itemheight; HPEN hPen, hOldPen; - RECT rcClip, rcItem; + RECT rcClip, rcItem = {0}; POINT Origin; RANGE colRange; ITERATOR j; + BOOL rmost = FALSE; TRACE("()\n"); @@ -4173,7 +4182,12 @@ static void LISTVIEW_RefreshReportGrid(LISTVIEW_INFO *infoPtr, HDC hdc) LISTVIEW_GetHeaderRect(infoPtr, colRange.upper - 1, &rcItem); if (rcItem.left + Origin.x < rcClip.right) break; } - iterator_rangeitems(&j, colRange); + /* is right most vertical line visible? */ + if (DPA_GetPtrCount(infoPtr->hdpaColumns) > 0) + { + LISTVIEW_GetHeaderRect(infoPtr, DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, &rcItem); + rmost = (rcItem.right + Origin.x < rcClip.right); + } if ((hPen = CreatePen( PS_SOLID, 1, comctl32_color.clr3dFace ))) { @@ -4194,11 +4208,17 @@ static void LISTVIEW_RefreshReportGrid(LISTVIEW_INFO *infoPtr, HDC hdc) LineTo (hdc, rcItem.left, rcItem.bottom); } iterator_destroy(&j); + /* draw rightmost grid line if visible */ + if (rmost) + { + MoveToEx (hdc, rcItem.right, rcItem.top, NULL); + LineTo (hdc, rcItem.right, rcItem.bottom); + } /* draw the horizontial lines for the rows */ itemheight = LISTVIEW_CalculateItemHeight(infoPtr); - rcItem.left = infoPtr->rcList.left + Origin.x; - rcItem.right = infoPtr->rcList.right + Origin.x; + rcItem.left = infoPtr->rcList.left; + rcItem.right = infoPtr->rcList.right; rcItem.bottom = rcItem.top = Origin.y - 1; MoveToEx(hdc, rcItem.left, rcItem.top, NULL); LineTo(hdc, rcItem.right, rcItem.top); @@ -4358,15 +4378,14 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *prcEra /* if we have a focus rect, draw it */ if (infoPtr->bFocus) - DrawFocusRect(hdc, &infoPtr->rcFocus); + LISTVIEW_DrawFocusRect(infoPtr, hdc); } iterator_destroy(&i); enddraw: /* For LVS_EX_GRIDLINES go and draw lines */ /* This includes the case where there were *no* items */ - if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_REPORT && - infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) + if ((uView == LVS_REPORT) && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) LISTVIEW_RefreshReportGrid(infoPtr, hdc); if (cdmode & CDRF_NOTIFYPOSTPAINT) @@ -5550,6 +5569,8 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, /* apparently, we should not callback for lParam in LVS_OWNERDATA */ if ((lpLVItem->mask & ~(LVIF_STATE | LVIF_PARAM)) || infoPtr->uCallbackMask) { + UINT mask = lpLVItem->mask; + /* NOTE: copy only fields which we _know_ are initialized, some apps * depend on the uninitialized fields being 0 */ dispInfo.item.mask = lpLVItem->mask & ~LVIF_PARAM; @@ -5557,34 +5578,49 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, dispInfo.item.iSubItem = isubitem; if (lpLVItem->mask & LVIF_TEXT) { - dispInfo.item.pszText = lpLVItem->pszText; - dispInfo.item.cchTextMax = lpLVItem->cchTextMax; + if (lpLVItem->mask & LVIF_NORECOMPUTE) + /* reset mask */ + dispInfo.item.mask &= ~(LVIF_TEXT | LVIF_NORECOMPUTE); + else + { + dispInfo.item.pszText = lpLVItem->pszText; + dispInfo.item.cchTextMax = lpLVItem->cchTextMax; + } } if (lpLVItem->mask & LVIF_STATE) dispInfo.item.stateMask = lpLVItem->stateMask & infoPtr->uCallbackMask; - notify_dispinfoT(infoPtr, LVN_GETDISPINFOW, &dispInfo, isW); - dispInfo.item.stateMask = lpLVItem->stateMask; - if (lpLVItem->mask & (LVIF_GROUPID|LVIF_COLUMNS)) + /* could be zeroed on LVIF_NORECOMPUTE case */ + if (dispInfo.item.mask != 0) { - /* full size structure expected - _WIN32IE >= 0x560 */ - *lpLVItem = dispInfo.item; + notify_dispinfoT(infoPtr, LVN_GETDISPINFOW, &dispInfo, isW); + dispInfo.item.stateMask = lpLVItem->stateMask; + if (lpLVItem->mask & (LVIF_GROUPID|LVIF_COLUMNS)) + { + /* full size structure expected - _WIN32IE >= 0x560 */ + *lpLVItem = dispInfo.item; + } + else if (lpLVItem->mask & LVIF_INDENT) + { + /* indent member expected - _WIN32IE >= 0x300 */ + memcpy(lpLVItem, &dispInfo.item, offsetof( LVITEMW, iGroupId )); + } + else + { + /* minimal structure expected */ + memcpy(lpLVItem, &dispInfo.item, offsetof( LVITEMW, iIndent )); + } + lpLVItem->mask = mask; + TRACE(" getdispinfo(1):lpLVItem=%s\n", debuglvitem_t(lpLVItem, isW)); } - else if (lpLVItem->mask & LVIF_INDENT) - { - /* indent member expected - _WIN32IE >= 0x300 */ - memcpy(lpLVItem, &dispInfo.item, offsetof( LVITEMW, iGroupId )); - } - else - { - /* minimal structure expected */ - memcpy(lpLVItem, &dispInfo.item, offsetof( LVITEMW, iIndent )); - } - TRACE(" getdispinfo(1):lpLVItem=%s\n", debuglvitem_t(lpLVItem, isW)); } /* make sure lParam is zeroed out */ if (lpLVItem->mask & LVIF_PARAM) lpLVItem->lParam = 0; - + + /* callback marked pointer required here */ + if ((lpLVItem->mask & LVIF_TEXT) && (lpLVItem->mask & LVIF_NORECOMPUTE)) + lpLVItem->pszText = LPSTR_TEXTCALLBACKW; + /* we store only a little state, so if we're not asked, we're done */ if (!(lpLVItem->mask & LVIF_STATE) || isubitem) return TRUE; @@ -5641,7 +5677,8 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, } /* Apps depend on calling back for text if it is NULL or LPSTR_TEXTCALLBACKW */ - if ((lpLVItem->mask & LVIF_TEXT) && !is_textW(pItemHdr->pszText)) + if ((lpLVItem->mask & LVIF_TEXT) && !(lpLVItem->mask & LVIF_NORECOMPUTE) && + !is_textW(pItemHdr->pszText)) { dispInfo.item.mask |= LVIF_TEXT; dispInfo.item.pszText = lpLVItem->pszText; @@ -5688,7 +5725,8 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, } else if (lpLVItem->mask & LVIF_TEXT) { - if (isW) lpLVItem->pszText = pItemHdr->pszText; + /* if LVN_GETDISPINFO's disabled with LVIF_NORECOMPUTE return callback placeholder */ + if (isW || !is_textW(pItemHdr->pszText)) lpLVItem->pszText = pItemHdr->pszText; else textcpynT(lpLVItem->pszText, isW, pItemHdr->pszText, TRUE, lpLVItem->cchTextMax); } @@ -5764,7 +5802,12 @@ static BOOL LISTVIEW_GetItemExtT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVIte pszText = lpLVItem->pszText; bResult = LISTVIEW_GetItemT(infoPtr, lpLVItem, isW); if (bResult && lpLVItem->pszText != pszText) - textcpynT(pszText, isW, lpLVItem->pszText, isW, lpLVItem->cchTextMax); + { + if (lpLVItem->pszText != LPSTR_TEXTCALLBACKW) + textcpynT(pszText, isW, lpLVItem->pszText, isW, lpLVItem->cchTextMax); + else + pszText = LPSTR_TEXTCALLBACKW; + } lpLVItem->pszText = pszText; return bResult; @@ -8125,6 +8168,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->nMeasureItemHeight = 0; infoPtr->xTrackLine = -1; /* no track line */ infoPtr->itemEdit.fEnabled = FALSE; + infoPtr->iVersion = COMCTL32_VERSION; /* get default font (icon title) */ SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0); @@ -9049,9 +9093,21 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE } /* when shrinking the last column clear the now unused field */ - if (lpnmh->iItem == DPA_GetPtrCount(infoPtr->hdpaColumns) - 1 && dx < 0) + if (lpnmh->iItem == DPA_GetPtrCount(infoPtr->hdpaColumns) - 1) + { + RECT right; + rcCol.right -= dx; + /* deal with right from rightmost column area */ + right.left = rcCol.right; + right.top = rcCol.top; + right.bottom = rcCol.bottom; + right.right = infoPtr->rcList.right; + + LISTVIEW_InvalidateRect(infoPtr, &right); + } + LISTVIEW_InvalidateRect(infoPtr, &rcCol); } } @@ -9739,6 +9795,47 @@ static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iSta /*** * DESCRIPTION: + * Processes CCM_GETVERSION messages. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * + * RETURN: + * Current version + */ +static inline LRESULT LISTVIEW_GetVersion(LISTVIEW_INFO *infoPtr) +{ + return infoPtr->iVersion; +} + +/*** + * DESCRIPTION: + * Processes CCM_SETVERSION messages. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] iVersion : version to be set + * + * RETURN: + * -1 when requested version is greater then DLL version; + * previous version otherwise + */ +static LRESULT LISTVIEW_SetVersion(LISTVIEW_INFO *infoPtr, DWORD iVersion) +{ + INT iOldVersion = infoPtr->iVersion; + + if (iVersion > COMCTL32_VERSION) + return -1; + + infoPtr->iVersion = iVersion; + + TRACE("new version %d\n", iVersion); + + return iOldVersion; +} + +/*** + * DESCRIPTION: * Window procedure of the listview control. * */ @@ -10106,6 +10203,12 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case LVM_UPDATE: return LISTVIEW_Update(infoPtr, (INT)wParam); + case CCM_GETVERSION: + return LISTVIEW_GetVersion(infoPtr); + + case CCM_SETVERSION: + return LISTVIEW_SetVersion(infoPtr, wParam); + case WM_CHAR: return LISTVIEW_ProcessLetterKeys( infoPtr, wParam, lParam ); diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 5d40546ea8f..7be6b71592f 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -158,6 +158,10 @@ static const struct message listview_getorderarray_seq[] = { { 0 } }; +static const struct message empty_seq[] = { + { 0 } +}; + struct subclass_info { WNDPROC oldproc; @@ -801,6 +805,20 @@ static void test_items(void) ok(r != 0, "ret %d\n", r); todo_wine ok(item.state == LVIS_DROPHILITED, "got state %x, expected %x\n", item.state, LVIS_DROPHILITED); + /* some notnull but meaningless masks */ + memset (&item, 0, sizeof(item)); + item.mask = LVIF_NORECOMPUTE; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + ok(r != 0, "ret %d\n", r); + memset (&item, 0, sizeof(item)); + item.mask = LVIF_DI_SETITEM; + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + ok(r != 0, "ret %d\n", r); + DestroyWindow(hwnd); } @@ -1835,6 +1853,79 @@ static void test_ownerdata(void) DestroyWindow(hwnd); } +static void test_norecompute(void) +{ + static CHAR testA[] = "test"; + CHAR buff[10]; + LVITEMA item; + HWND hwnd; + DWORD res; + + /* self containing control */ + hwnd = create_listview_control(0); + ok(hwnd != NULL, "failed to create a listview window\n"); + memset(&item, 0, sizeof(item)); + item.mask = LVIF_TEXT | LVIF_STATE; + item.iItem = 0; + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + item.pszText = testA; + res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item); + expect(0, res); + /* retrieve with LVIF_NORECOMPUTE */ + item.mask = LVIF_TEXT | LVIF_NORECOMPUTE; + item.iItem = 0; + item.pszText = buff; + item.cchTextMax = sizeof(buff)/sizeof(CHAR); + res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item); + expect(TRUE, res); + ok(lstrcmp(buff, testA) == 0, "Expected (%s), got (%s)\n", testA, buff); + + item.mask = LVIF_TEXT; + item.iItem = 1; + item.pszText = LPSTR_TEXTCALLBACK; + res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item); + expect(1, res); + + item.mask = LVIF_TEXT | LVIF_NORECOMPUTE; + item.iItem = 1; + item.pszText = buff; + item.cchTextMax = sizeof(buff)/sizeof(CHAR); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item); + expect(TRUE, res); + ok(item.pszText == LPSTR_TEXTCALLBACK, "Expected (%p), got (%p)\n", + LPSTR_TEXTCALLBACK, (VOID*)item.pszText); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq", FALSE); + + DestroyWindow(hwnd); + + /* LVS_OWNERDATA */ + hwnd = create_listview_control(LVS_OWNERDATA); + ok(hwnd != NULL, "failed to create a listview window\n"); + + item.mask = LVIF_STATE; + item.stateMask = LVIS_SELECTED; + item.state = LVIS_SELECTED; + item.iItem = 0; + res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item); + expect(0, res); + + item.mask = LVIF_TEXT | LVIF_NORECOMPUTE; + item.iItem = 0; + item.pszText = buff; + item.cchTextMax = sizeof(buff)/sizeof(CHAR); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item); + expect(TRUE, res); + ok(item.pszText == LPSTR_TEXTCALLBACK, "Expected (%p), got (%p)\n", + LPSTR_TEXTCALLBACK, (VOID*)item.pszText); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq 2", FALSE); + + DestroyWindow(hwnd); +} + START_TEST(listview) { HMODULE hComctl32; @@ -1875,4 +1966,5 @@ START_TEST(listview) test_subitem_rect(); test_sorting(); test_ownerdata(); + test_norecompute(); } diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index f29f1e67e2c..f6fb60c5581 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -4993,6 +4993,12 @@ static LRESULT CALLBACK import_file_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, data = (struct ImportWizData *)page->lParam; SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data); + if (data->fileName) + { + HWND fileNameEdit = GetDlgItem(hwnd, IDC_IMPORT_FILENAME); + + SendMessageW(fileNameEdit, WM_SETTEXT, 0, (LPARAM)data->fileName); + } break; } case WM_NOTIFY: @@ -5383,10 +5389,15 @@ static BOOL show_import_ui(DWORD dwFlags, HWND hwndParent, data.dwFlags = dwFlags; data.pwszWizardTitle = pwszWizardTitle; if (pImportSrc) + { memcpy(&data.importSrc, pImportSrc, sizeof(data.importSrc)); + data.fileName = (LPWSTR)pImportSrc->u.pwszFileName; + } else + { memset(&data.importSrc, 0, sizeof(data.importSrc)); - data.fileName = NULL; + data.fileName = NULL; + } data.freeSource = FALSE; data.hDestCertStore = hDestCertStore; data.freeDest = FALSE; @@ -5470,7 +5481,8 @@ static BOOL show_import_ui(DWORD dwFlags, HWND hwndParent, hdr.u4.pszbmWatermark = MAKEINTRESOURCEW(IDB_CERT_WATERMARK); hdr.u5.pszbmHeader = MAKEINTRESOURCEW(IDB_CERT_HEADER); PropertySheetW(&hdr); - HeapFree(GetProcessHeap(), 0, data.fileName); + if (data.fileName != data.importSrc.u.pwszFileName) + HeapFree(GetProcessHeap(), 0, data.fileName); if (data.freeSource && data.importSrc.dwSubjectChoice == CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE) CertCloseStore(data.importSrc.u.hCertStore, 0); diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index df9794ff12b..3f782baf1dc 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -39,6 +39,7 @@ ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') /* TRACE helper functions */ const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology); @@ -149,8 +150,12 @@ struct d3d10_pixel_shader { const struct ID3D10PixelShaderVtbl *vtbl; LONG refcount; + + IWineD3DPixelShader *wined3d_shader; }; +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code); + /* Layered device */ enum dxgi_device_layer_id { diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 2b704b35c10..5c91cbd5f40 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -1023,11 +1023,21 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShaderWithStreamOutp static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10PixelShader **shader) { + struct d3d10_device *This = (struct d3d10_device *)iface; struct d3d10_pixel_shader *object; + const DWORD *shader_code; + HRESULT hr; - FIXME("iface %p, byte_code %p, byte_code_length %lu, shader %p stub!\n", + TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p\n", iface, byte_code, byte_code_length, shader); + hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_code); + if (FAILED(hr)) + { + ERR("Failed to extract shader, hr %#x\n", hr); + return hr; + } + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { @@ -1038,6 +1048,15 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *if object->vtbl = &d3d10_pixel_shader_vtbl; object->refcount = 1; + hr = IWineD3DDevice_CreatePixelShader(This->wined3d_device, + shader_code, &object->wined3d_shader, (IUnknown *)object); + if (FAILED(hr)) + { + ERR("CreatePixelShader failed, hr %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + *shader = (ID3D10PixelShader *)object; return S_OK; diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index b614779bec1..8b3d01e442c 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -24,6 +24,37 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); +static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +{ + const DWORD **shader_data = ctx; + char tag_str[5]; + + switch(tag) + { + case TAG_SHDR: + *shader_data = (const DWORD *)data; + return S_OK; + + default: + memcpy(tag_str, &tag, 4); + tag_str[4] = '\0'; + FIXME("Unhandled chunk %s\n", tag_str); + return S_OK; + } +} + +HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, const DWORD **shader_code) +{ + HRESULT hr; + + hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_code); + if (!*shader_code) hr = E_FAIL; + + if (FAILED(hr)) ERR("Failed to parse shader, hr %#x\n", hr); + + return hr; +} + /* IUnknown methods */ static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface, diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index c9afe173ab9..c38d8cc8b30 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -601,6 +601,8 @@ struct IDirect3DVertexShader8Impl { IWineD3DVertexShader *wineD3DVertexShader; }; +#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256 + /* ------------------------ */ /* IDirect3DPixelShaderImpl */ diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index a33bdbc36e2..f5ab8b3a73a 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -359,6 +359,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){ pCaps->VertexShaderVersion = D3DVS_VERSION(1,1); } + pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); TRACE("Returning %p %p\n", This, pCaps); return hrc; @@ -1998,6 +1999,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV HRESULT hr; TRACE("(%p) : Relay\n", This); + if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) { + WARN("Trying to access %u constants, but d3d8 only supports %u\n", + Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF); + return D3DERR_INVALIDCALL; + } + EnterCriticalSection(&d3d8_cs); hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount); LeaveCriticalSection(&d3d8_cs); @@ -2009,6 +2016,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV HRESULT hr; TRACE("(%p) : Relay\n", This); + if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) { + WARN("Trying to access %u constants, but d3d8 only supports %u\n", + Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF); + return D3DERR_INVALIDCALL; + } + EnterCriticalSection(&d3d8_cs); hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount); LeaveCriticalSection(&d3d8_cs); diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 64fc3605d43..d39d3d64768 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -265,6 +265,7 @@ static HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Ada if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){ pCaps->VertexShaderVersion = D3DVS_VERSION(1,1); } + pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); TRACE("(%p) returning %p\n", This, pCaps); return hrc; diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 25b6ae2434a..7e439749a7b 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -497,6 +497,8 @@ typedef struct IDirect3DVertexShader9Impl { LPDIRECT3DDEVICE9EX parentDevice; } IDirect3DVertexShader9Impl; +#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 + /* --------------------- */ /* IDirect3DPixelShader9 */ /* --------------------- */ diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 229368afb80..e9547a764e4 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -311,6 +311,8 @@ void filter_caps(D3DCAPS9* pCaps) D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP | D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV; + + pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); } static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 2e0f9927b75..0663a9178c3 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -9603,7 +9603,7 @@ static void yuv_color_test(IDirect3DDevice9 *device) { color = getPixelColor(device, 600, 240); ok(color_match(color, ref_color_right, 16), "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n", - test_data[i].in, color, ref_color_left, fmt_string); + test_data[i].in, color, ref_color_right, fmt_string); } IDirect3DSurface9_Release(surface); } diff --git a/dlls/d3d9/vertexshader.c b/dlls/d3d9/vertexshader.c index 6478b68656f..fd2837d53be 100644 --- a/dlls/d3d9/vertexshader.c +++ b/dlls/d3d9/vertexshader.c @@ -192,6 +192,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX HRESULT hr; TRACE("(%p) : Relay\n", This); + if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) { + WARN("Trying to access %u constants, but d3d9 only supports %u\n", + Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF); + return D3DERR_INVALIDCALL; + } + EnterCriticalSection(&d3d9_cs); hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount); LeaveCriticalSection(&d3d9_cs); @@ -202,6 +208,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; HRESULT hr; + if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) { + WARN("Trying to access %u constants, but d3d9 only supports %u\n", + Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF); + return D3DERR_INVALIDCALL; + } + TRACE("(%p) : Relay\n", This); EnterCriticalSection(&d3d9_cs); hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount); diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 99626d09393..2f2c63e5fb5 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1340,7 +1340,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_ localised_family = NULL; if(!fake_family) { localised_family = get_familyname(ft_face); - if(localised_family && !strcmpW(localised_family, english_family)) { + if(localised_family && !strcmpiW(localised_family, english_family)) { HeapFree(GetProcessHeap(), 0, localised_family); localised_family = NULL; } @@ -1349,7 +1349,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_ family = NULL; LIST_FOR_EACH(family_elem_ptr, &font_list) { family = LIST_ENTRY(family_elem_ptr, Family, entry); - if(!strcmpW(family->FamilyName, localised_family ? localised_family : english_family)) + if(!strcmpiW(family->FamilyName, localised_family ? localised_family : english_family)) break; family = NULL; } @@ -1410,7 +1410,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_ while(face_elem_ptr) { face = LIST_ENTRY(face_elem_ptr, Face, entry); face_elem_ptr = list_next(&family->faces, face_elem_ptr); - if(!strcmpW(face->StyleName, StyleW) && + if(!strcmpiW(face->StyleName, StyleW) && (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) ))) { TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n", debugstr_w(family->FamilyName), debugstr_w(StyleW), @@ -1651,8 +1651,6 @@ static BOOL init_system_links(void) index = 0; while(RegEnumValueW(hkey, index++, value, &val_len, NULL, &type, (LPBYTE)data, &data_len) == ERROR_SUCCESS) { - TRACE("%s:\n", debugstr_w(value)); - memset(&fs, 0, sizeof(fs)); font_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*font_link)); psub = get_font_subst(&font_subst_list, value, -1); @@ -1663,7 +1661,7 @@ static BOOL init_system_links(void) WCHAR *face_name; CHILD_FONT *child_font; - TRACE("\t%s\n", debugstr_w(entry)); + TRACE("%s: %s\n", debugstr_w(value), debugstr_w(entry)); next = entry + strlenW(entry) + 1; @@ -3199,7 +3197,7 @@ static BOOL create_child_font_list(GdiFont *font) LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry) { - if(!strcmpW(font_link->font_name, font->name)) + if(!strcmpiW(font_link->font_name, font->name)) { TRACE("found entry in system list\n"); LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry) @@ -3220,10 +3218,10 @@ static BOOL create_child_font_list(GdiFont *font) */ if (use_default_fallback && font->charset != SYMBOL_CHARSET && font->charset != OEM_CHARSET && - strcmpW(font->name,szDefaultFallbackLink) != 0) + strcmpiW(font->name,szDefaultFallbackLink) != 0) LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry) { - if(!strcmpW(font_link->font_name,szDefaultFallbackLink)) + if(!strcmpiW(font_link->font_name,szDefaultFallbackLink)) { TRACE("found entry in default fallback list\n"); LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry) diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index 75f3310351e..bfbeee05670 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -1441,6 +1441,13 @@ static void test_GetDIBits(void) 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0 }; + static const BYTE dib_bits_1_9x[16 * 4] = + { + 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, + 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, + 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, + 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa + }; /* 2-bytes aligned 24-bit bitmap data: 16x16 */ static const BYTE bmp_bits_24[16 * 16*3] = { @@ -1592,15 +1599,21 @@ static void test_GetDIBits(void) } /* returned bits are DWORD aligned and upside down */ - ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n"); + ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) || + broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */ + "DIB bits don't match\n"); /* Test the palette indices */ memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256); SetLastError(0xdeadbeef); lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS); - - ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]); - ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]); + if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER) + win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n"); + else + { + ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]); + ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]); + } for (i = 2; i < 256; i++) ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]); @@ -1708,15 +1721,21 @@ static void test_GetDIBits(void) /* returned bits are DWORD aligned and upside down */ todo_wine - ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n"); + ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) || + broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */ + "DIB bits don't match\n"); /* Test the palette indices */ memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256); SetLastError(0xdeadbeef); lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS); - - ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]); - ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]); + if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER) + win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n"); + else + { + ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]); + ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]); + } for (i = 2; i < 256; i++) ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]); diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c index 661246c8df6..1efde38b134 100644 --- a/dlls/gdi32/tests/dc.c +++ b/dlls/gdi32/tests/dc.c @@ -253,10 +253,86 @@ static void test_CreateCompatibleDC(void) ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC); } +static void test_DC_bitmap(void) +{ + HDC hdc, hdcmem; + DWORD bits[64]; + HBITMAP hbmp, oldhbmp; + COLORREF col; + int i, bitspixel; + + /* fill bitmap data with b&w pattern */ + for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff; + + hdc = GetDC(0); + ok( hdc != NULL, "CreateDC rets %p\n", hdc); + bitspixel = GetDeviceCaps( hdc, BITSPIXEL); + /* create a memory dc */ + hdcmem = CreateCompatibleDC( hdc); + ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem); + /* tests */ + /* test monochrome bitmap: should always work */ + hbmp = CreateBitmap(32, 32, 1, 1, bits); + ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp); + oldhbmp = SelectObject( hdcmem, hbmp); + ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */ + col = GetPixel( hdcmem, 0, 0); + ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col); + col = GetPixel( hdcmem, 1, 1); + ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col); + col = GetPixel( hdcmem, 100, 1); + ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col); + SelectObject( hdcmem, oldhbmp); + DeleteObject( hbmp); + + /* test with 2 bits color depth, not likely to succeed */ + hbmp = CreateBitmap(16, 16, 1, 2, bits); + ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp); + oldhbmp = SelectObject( hdcmem, hbmp); + if( bitspixel != 2) + ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n"); + if( oldhbmp) SelectObject( hdcmem, oldhbmp); + DeleteObject( hbmp); + + /* test with 16 bits color depth, might succeed */ + hbmp = CreateBitmap(6, 6, 1, 16, bits); + ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp); + oldhbmp = SelectObject( hdcmem, hbmp); + if( bitspixel == 16) { + ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); + col = GetPixel( hdcmem, 0, 0); + ok( col == 0xffffff, + "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col); + col = GetPixel( hdcmem, 1, 1); + ok( col == 0x000000, + "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col); + } + if( oldhbmp) SelectObject( hdcmem, oldhbmp); + DeleteObject( hbmp); + + /* test with 32 bits color depth, probably succeed */ + hbmp = CreateBitmap(4, 4, 1, 32, bits); + ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp); + oldhbmp = SelectObject( hdcmem, hbmp); + if( bitspixel == 32) { + ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); + col = GetPixel( hdcmem, 0, 0); + ok( col == 0xffffff, + "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col); + col = GetPixel( hdcmem, 1, 1); + ok( col == 0x000000, + "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col); + } + if( oldhbmp) SelectObject( hdcmem, oldhbmp); + DeleteObject( hbmp); + ReleaseDC( 0, hdc ); +} + START_TEST(dc) { test_savedc(); test_savedc_2(); test_GdiConvertToDevmodeW(); test_CreateCompatibleDC(); + test_DC_bitmap(); } diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index c10d6e836cd..88e1797bacc 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1785,7 +1785,9 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset) ok(efdw.total > 0, "fonts enumerated: NULL\n"); ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n"); ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n"); - ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n"); + ok(russian_charset > 0 || + broken(russian_charset == 0), /* NT4 */ + "NULL family should enumerate RUSSIAN_CHARSET\n"); } efdw.total = 0; diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index f0c9b206811..74e7764276b 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -108,14 +108,38 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) break; } - case BrushTypeLinearGradient: - *clone = GdipAlloc(sizeof(GpLineGradient)); - if(!*clone) return OutOfMemory; + case BrushTypeLinearGradient:{ + GpLineGradient *dest, *src; + INT count; + + dest = GdipAlloc(sizeof(GpLineGradient)); + if(!dest) return OutOfMemory; + + src = (GpLineGradient*)brush; + + memcpy(dest, src, sizeof(GpLineGradient)); + + dest->brush.gdibrush = CreateSolidBrush(dest->brush.lb.lbColor); + + count = dest->blendcount; + dest->blendfac = GdipAlloc(count * sizeof(REAL)); + dest->blendpos = GdipAlloc(count * sizeof(REAL)); + + if (!dest->blendfac || !dest->blendpos) + { + GdipFree(dest->blendfac); + GdipFree(dest->blendpos); + DeleteObject(dest->brush.gdibrush); + GdipFree(dest); + return OutOfMemory; + } - memcpy(*clone, brush, sizeof(GpLineGradient)); + memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); + memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); - (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor); + *clone = &dest->brush; break; + } case BrushTypeTextureFill: *clone = GdipAlloc(sizeof(GpTexture)); if(!*clone) return OutOfMemory; @@ -226,6 +250,23 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint, (*line)->wrap = wrap; (*line)->gamma = FALSE; + (*line)->blendcount = 1; + (*line)->blendfac = GdipAlloc(sizeof(REAL)); + (*line)->blendpos = GdipAlloc(sizeof(REAL)); + + if (!(*line)->blendfac || !(*line)->blendpos) + { + GdipFree((*line)->blendfac); + GdipFree((*line)->blendpos); + DeleteObject((*line)->brush.gdibrush); + GdipFree(*line); + *line = NULL; + return OutOfMemory; + } + + (*line)->blendfac[0] = 1.0f; + (*line)->blendpos[0] = 1.0f; + return Ok; } @@ -765,7 +806,10 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) GdipFree(((GpPathGradient*) brush)->blendpos); break; case BrushTypeSolidColor: + break; case BrushTypeLinearGradient: + GdipFree(((GpLineGradient*)brush)->blendfac); + GdipFree(((GpLineGradient*)brush)->blendpos); break; case BrushTypeTextureFill: GdipDeleteMatrix(((GpTexture*)brush)->transform); @@ -1071,15 +1115,64 @@ GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture* brush, } GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, - GDIPCONST REAL *blend, GDIPCONST REAL* positions, INT count) + GDIPCONST REAL *factors, GDIPCONST REAL* positions, INT count) { - static int calls; + REAL *new_blendfac, *new_blendpos; - if(!brush || !blend || !positions || count <= 0) + TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); + + if(!brush || !factors || !positions || count <= 0 || + (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f))) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + new_blendfac = GdipAlloc(count * sizeof(REAL)); + new_blendpos = GdipAlloc(count * sizeof(REAL)); + + if (!new_blendfac || !new_blendpos) + { + GdipFree(new_blendfac); + GdipFree(new_blendpos); + return OutOfMemory; + } + + memcpy(new_blendfac, factors, count * sizeof(REAL)); + memcpy(new_blendpos, positions, count * sizeof(REAL)); + + GdipFree(brush->blendfac); + GdipFree(brush->blendpos); + + brush->blendcount = count; + brush->blendfac = new_blendfac; + brush->blendpos = new_blendpos; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors, + REAL *positions, INT count) +{ + TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); + + if (!brush || !factors || !positions || count <= 0) + return InvalidParameter; + + if (count < brush->blendcount) + return InsufficientBuffer; + + memcpy(factors, brush->blendfac, brush->blendcount * sizeof(REAL)); + memcpy(positions, brush->blendpos, brush->blendcount * sizeof(REAL)); + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count) +{ + TRACE("(%p, %p)\n", brush, count); + + if (!brush || !count) + return InvalidParameter; + + *count = brush->blendcount; return Ok; } diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 6454765d85c..68540e40ad7 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -36,6 +36,8 @@ WINE_DEFAULT_DEBUG_CHANNEL (gdiplus); static const REAL mm_per_inch = 25.4; static const REAL inch_per_point = 1.0/72.0; +static GpFontCollection installedFontCollection = {0}; + static inline REAL get_dpi (void) { REAL dpi; @@ -936,5 +938,7 @@ GpStatus WINGDIPAPI GdipNewInstalledFontCollection( if (!fontCollection) return InvalidParameter; - return NotImplemented; + *fontCollection = &installedFontCollection; + + return Ok; } diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index ba9851858a9..a9d4c9da9f2 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -42,7 +42,7 @@ @ stub GdipBitmapGetHistogramSize @ stdcall GdipBitmapGetPixel(ptr long long ptr) @ stdcall GdipBitmapLockBits(ptr ptr long long ptr) -@ stub GdipBitmapSetPixel +@ stdcall GdipBitmapSetPixel(ptr long long long) @ stdcall GdipBitmapSetResolution(ptr long long) @ stdcall GdipBitmapUnlockBits(ptr ptr) @ stdcall GdipClearPathMarkers(ptr) @@ -300,8 +300,8 @@ @ stdcall GdipGetImageVerticalResolution(ptr ptr) @ stdcall GdipGetImageWidth(ptr ptr) @ stdcall GdipGetInterpolationMode(ptr ptr) -@ stub GdipGetLineBlend -@ stub GdipGetLineBlendCount +@ stdcall GdipGetLineBlend(ptr ptr ptr long) +@ stdcall GdipGetLineBlendCount(ptr ptr) @ stdcall GdipGetLineColors(ptr ptr) @ stdcall GdipGetLineGammaCorrection(ptr ptr) @ stub GdipGetLinePresetBlend diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index dbeebe3380e..e038bafa241 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -91,6 +91,7 @@ struct GpPen{ struct GpGraphics{ HDC hdc; HWND hwnd; + BOOL owndc; SmoothingMode smoothing; CompositingQuality compqual; InterpolationMode interpolation; @@ -144,6 +145,9 @@ struct GpLineGradient{ ARGB endcolor; GpWrapMode wrap; BOOL gamma; + REAL* blendfac; /* blend factors */ + REAL* blendpos; /* blend positions */ + INT blendcount; }; struct GpTexture{ diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 2a98ee51b1b..36cb324f839 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -924,6 +924,7 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra (*graphics)->hdc = hdc; (*graphics)->hwnd = WindowFromDC(hdc); + (*graphics)->owndc = FALSE; (*graphics)->smoothing = SmoothingModeDefault; (*graphics)->compqual = CompositingQualityDefault; (*graphics)->interpolation = InterpolationModeDefault; @@ -940,13 +941,20 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics) { GpStatus ret; + HDC hdc; TRACE("(%p, %p)\n", hwnd, graphics); - if((ret = GdipCreateFromHDC(GetDC(hwnd), graphics)) != Ok) + hdc = GetDC(hwnd); + + if((ret = GdipCreateFromHDC(hdc, graphics)) != Ok) + { + ReleaseDC(hwnd, hdc); return ret; + } (*graphics)->hwnd = hwnd; + (*graphics)->owndc = TRUE; return Ok; } @@ -1081,7 +1089,7 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) if(!graphics) return InvalidParameter; if(graphics->busy) return ObjectBusy; - if(graphics->hwnd) + if(graphics->owndc) ReleaseDC(graphics->hwnd, graphics->hdc); GdipDeleteRegion(graphics->clip); diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 55522258891..fde6ab3ceae 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -87,6 +87,21 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, return NotImplemented; } +GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, + ARGB color) +{ + static int calls; + TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color); + + if(!bitmap) + return InvalidParameter; + + if(!(calls++)) + FIXME("not implemented\n"); + + return NotImplemented; +} + /* This function returns a pointer to an array of pixels that represents the * bitmap. The *entire* bitmap is locked according to the lock mode specified by * flags. It is correct behavior that a user who calls this function with write diff --git a/dlls/gdiplus/tests/brush.c b/dlls/gdiplus/tests/brush.c index d2cbd3c77e3..cabbd7f26b5 100644 --- a/dlls/gdiplus/tests/brush.c +++ b/dlls/gdiplus/tests/brush.c @@ -344,6 +344,113 @@ static void test_gradientgetrect(void) status = GdipDeleteBrush((GpBrush*)brush); } +static void test_lineblend(void) +{ + GpLineGradient *brush; + GpStatus status; + GpPointF pt1, pt2; + INT count=10; + int i; + const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f}; + const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f}; + REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f}; + REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f}; + + pt1.X = pt1.Y = 1.0; + pt2.X = pt2.Y = 100.0; + status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush); + expect(Ok, status); + + status = GdipGetLineBlendCount(NULL, &count); + expect(InvalidParameter, status); + + status = GdipGetLineBlendCount(brush, NULL); + expect(InvalidParameter, status); + + status = GdipGetLineBlendCount(brush, &count); + expect(Ok, status); + expect(1, count); + + status = GdipGetLineBlend(NULL, res_factors, res_positions, 1); + expect(InvalidParameter, status); + + status = GdipGetLineBlend(brush, NULL, res_positions, 1); + expect(InvalidParameter, status); + + status = GdipGetLineBlend(brush, res_factors, NULL, 1); + expect(InvalidParameter, status); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 0); + expect(InvalidParameter, status); + + status = GdipGetLineBlend(brush, res_factors, res_positions, -1); + expect(InvalidParameter, status); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 1); + expect(Ok, status); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 2); + expect(Ok, status); + + status = GdipSetLineBlend(NULL, factors, positions, 5); + expect(InvalidParameter, status); + + status = GdipSetLineBlend(brush, NULL, positions, 5); + expect(InvalidParameter, status); + + status = GdipSetLineBlend(brush, factors, NULL, 5); + expect(InvalidParameter, status); + + status = GdipSetLineBlend(brush, factors, positions, 0); + expect(InvalidParameter, status); + + status = GdipSetLineBlend(brush, factors, positions, -1); + expect(InvalidParameter, status); + + /* leave off the 0.0 position */ + status = GdipSetLineBlend(brush, &factors[1], &positions[1], 4); + expect(InvalidParameter, status); + + /* leave off the 1.0 position */ + status = GdipSetLineBlend(brush, factors, positions, 4); + expect(InvalidParameter, status); + + status = GdipSetLineBlend(brush, factors, positions, 5); + expect(Ok, status); + + status = GdipGetLineBlendCount(brush, &count); + expect(Ok, status); + expect(5, count); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 4); + expect(InsufficientBuffer, status); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 5); + expect(Ok, status); + + for (i=0; i<5; i++) + { + expectf(factors[i], res_factors[i]); + expectf(positions[i], res_positions[i]); + } + + status = GdipGetLineBlend(brush, res_factors, res_positions, 6); + expect(Ok, status); + + status = GdipSetLineBlend(brush, factors, positions, 1); + expect(Ok, status); + + status = GdipGetLineBlendCount(brush, &count); + expect(Ok, status); + expect(1, count); + + status = GdipGetLineBlend(brush, res_factors, res_positions, 1); + expect(Ok, status); + + status = GdipDeleteBrush((GpBrush*)brush); + expect(Ok, status); +} + START_TEST(brush) { struct GdiplusStartupInput gdiplusStartupInput; @@ -365,6 +472,7 @@ START_TEST(brush) test_transform(); test_texturewrap(); test_gradientgetrect(); + test_lineblend(); GdiplusShutdown(gdiplusToken); } diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c index 7d6582fe352..0da5b2f7bc3 100644 --- a/dlls/gdiplus/tests/font.c +++ b/dlls/gdiplus/tests/font.c @@ -340,6 +340,19 @@ monospace: expect (Ok, stat); } +static void test_installedfonts (void) +{ + GpStatus stat; + GpFontCollection* collection=NULL; + + stat = GdipNewInstalledFontCollection(NULL); + expect (InvalidParameter, stat); + + stat = GdipNewInstalledFontCollection(&collection); + expect (Ok, stat); + ok (collection != NULL, "got NULL font collection\n"); +} + START_TEST(font) { struct GdiplusStartupInput gdiplusStartupInput; @@ -357,6 +370,7 @@ START_TEST(font) test_fontfamily(); test_fontfamily_properties(); test_getgenerics(); + test_installedfonts(); GdiplusShutdown(gdiplusToken); } diff --git a/dlls/inetmib1/tests/main.c b/dlls/inetmib1/tests/main.c index 13613fd9d42..6c83d58e7fd 100644 --- a/dlls/inetmib1/tests/main.c +++ b/dlls/inetmib1/tests/main.c @@ -35,7 +35,7 @@ static void testInit(void) pInit = (void *)GetProcAddress(inetmib1, "SnmpExtensionInit"); if (!pInit) { - skip("no SnmpExtensionInit\n"); + win_skip("no SnmpExtensionInit\n"); return; } /* Crash @@ -72,7 +72,7 @@ static void testQuery(void) pQuery = (void *)GetProcAddress(inetmib1, "SnmpExtensionQuery"); if (!pQuery) { - skip("couldn't find SnmpExtensionQuery\n"); + win_skip("couldn't find SnmpExtensionQuery\n"); return; } /* Crash @@ -473,4 +473,5 @@ START_TEST(main) inetmib1 = LoadLibraryA("inetmib1"); testInit(); testQuery(); + FreeLibrary(inetmib1); } diff --git a/dlls/iphlpapi/ifenum.c b/dlls/iphlpapi/ifenum.c index f36fc99e896..19c3c3c952c 100644 --- a/dlls/iphlpapi/ifenum.c +++ b/dlls/iphlpapi/ifenum.c @@ -548,7 +548,7 @@ DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr, return ERROR_INVALID_DATA; } -static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) +DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) { DWORD ret; int fd; @@ -580,7 +580,7 @@ static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) return ret; } -static DWORD getInterfaceStatusByName(const char *name, PDWORD status) +DWORD getInterfaceStatusByName(const char *name, PDWORD status) { DWORD ret; int fd; diff --git a/dlls/iphlpapi/ifenum.h b/dlls/iphlpapi/ifenum.h index d4717508666..6835dcad3c2 100644 --- a/dlls/iphlpapi/ifenum.h +++ b/dlls/iphlpapi/ifenum.h @@ -112,4 +112,7 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags); */ char *toIPAddressString(unsigned int addr, char string[16]); +DWORD getInterfaceMtuByName(const char *name, PDWORD mtu); +DWORD getInterfaceStatusByName(const char *name, PDWORD status); + #endif /* ndef WINE_IFENUM_H_ */ diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index 24c4e94f214..794ece20936 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -18,6 +18,7 @@ @ stub FlushIpNetTableFromStack @ stdcall GetAdapterIndex( wstr ptr ) @ stub GetAdapterOrderMap +@ stdcall GetAdaptersAddresses( long long ptr ptr ptr ) @ stdcall GetAdaptersInfo( ptr ptr ) @ stdcall GetBestInterface( long ptr ) @ stdcall GetBestInterfaceEx( ptr ptr ) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 547b6667b48..8490c67990c 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -23,6 +23,12 @@ #include #include #include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif #ifdef HAVE_NETINET_IN_H # include #endif @@ -44,11 +50,16 @@ #include "iphlpapi.h" #include "ifenum.h" #include "ipstats.h" +#include "ipifcons.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); +#ifndef IF_NAMESIZE +#define IF_NAMESIZE 16 +#endif + #ifndef INADDR_NONE #define INADDR_NONE ~0UL #endif @@ -586,6 +597,168 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) return ret; } +static DWORD typeFromMibType(DWORD mib_type) +{ + switch (mib_type) + { + case MIB_IF_TYPE_ETHERNET: return IF_TYPE_ETHERNET_CSMACD; + case MIB_IF_TYPE_TOKENRING: return IF_TYPE_ISO88025_TOKENRING; + case MIB_IF_TYPE_PPP: return IF_TYPE_PPP; + case MIB_IF_TYPE_LOOPBACK: return IF_TYPE_SOFTWARE_LOOPBACK; + default: return IF_TYPE_OTHER; + } +} + +static ULONG addressesFromIndex(DWORD index, DWORD **addrs, ULONG *num_addrs) +{ + ULONG ret, i; + MIB_IPADDRTABLE *at; + + *num_addrs = 0; + if ((ret = getIPAddrTable(&at, GetProcessHeap(), 0))) return ret; + for (i = 0; i < at->dwNumEntries; i++) + { + if (at->table[i].dwIndex == index) (*num_addrs)++; + } + if (!(*addrs = HeapAlloc(GetProcessHeap(), 0, *num_addrs * sizeof(DWORD)))) + { + HeapFree(GetProcessHeap(), 0, at); + return ERROR_OUTOFMEMORY; + } + for (i = 0; i < at->dwNumEntries; i++) + { + if (at->table[i].dwIndex == index) (*addrs)[i] = at->table[i].dwAddr; + } + HeapFree(GetProcessHeap(), 0, at); + return ERROR_SUCCESS; +} + +static ULONG adapterAddressesFromIndex(DWORD index, IP_ADAPTER_ADDRESSES *aa, ULONG *size) +{ + ULONG ret, i, num_addrs, total_size; + DWORD *addrs; + + if ((ret = addressesFromIndex(index, &addrs, &num_addrs))) return ret; + + total_size = sizeof(IP_ADAPTER_ADDRESSES); + total_size += IF_NAMESIZE; + total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_addrs; + total_size += sizeof(struct sockaddr_in) * num_addrs; + + if (aa && *size >= total_size) + { + char name[IF_NAMESIZE], *ptr = (char *)aa + sizeof(IP_ADAPTER_ADDRESSES); + DWORD buflen, type, status; + + memset(aa, 0, sizeof(IP_ADAPTER_ADDRESSES)); + aa->Length = sizeof(IP_ADAPTER_ADDRESSES); + aa->IfIndex = index; + + getInterfaceNameByIndex(index, name); + memcpy(ptr, name, IF_NAMESIZE); + aa->AdapterName = ptr; + ptr += IF_NAMESIZE; + + if (num_addrs) + { + IP_ADAPTER_UNICAST_ADDRESS *ua; + struct sockaddr_in *sa; + + ua = aa->FirstUnicastAddress = (IP_ADAPTER_UNICAST_ADDRESS *)ptr; + for (i = 0; i < num_addrs; i++) + { + memset(ua, 0, sizeof(IP_ADAPTER_UNICAST_ADDRESS)); + ua->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS); + ua->Address.iSockaddrLength = sizeof(struct sockaddr_in); + ua->Address.lpSockaddr = (SOCKADDR *)((char *)ua + ua->Length); + + sa = (struct sockaddr_in *)ua->Address.lpSockaddr; + sa->sin_family = AF_INET; + sa->sin_addr.s_addr = addrs[i]; + sa->sin_port = 0; + + ptr += ua->Length + ua->Address.iSockaddrLength; + if (i < num_addrs - 1) + { + ua->Next = (IP_ADAPTER_UNICAST_ADDRESS *)ptr; + ua = ua->Next; + } + } + } + + buflen = MAX_INTERFACE_PHYSADDR; + getInterfacePhysicalByIndex(index, &buflen, aa->PhysicalAddress, &type); + aa->PhysicalAddressLength = buflen; + aa->IfType = typeFromMibType(type); + + getInterfaceMtuByName(name, &aa->Mtu); + + getInterfaceStatusByName(name, &status); + if (status == MIB_IF_OPER_STATUS_OPERATIONAL) aa->OperStatus = IfOperStatusUp; + else if (status == MIB_IF_OPER_STATUS_NON_OPERATIONAL) aa->OperStatus = IfOperStatusDown; + else aa->OperStatus = IfOperStatusUnknown; + } + *size = total_size; + HeapFree(GetProcessHeap(), 0, addrs); + return ERROR_SUCCESS; +} + +ULONG WINAPI GetAdaptersAddresses(ULONG family, ULONG flags, PVOID reserved, + PIP_ADAPTER_ADDRESSES aa, PULONG buflen) +{ + InterfaceIndexTable *table; + ULONG i, size, total_size, ret = ERROR_NO_DATA; + + if (!buflen) return ERROR_INVALID_PARAMETER; + + if (family == AF_INET6 || family == AF_UNSPEC) + FIXME("no support for IPv6 addresses\n"); + + if (family != AF_INET && family != AF_UNSPEC) return ERROR_NO_DATA; + + table = getInterfaceIndexTable(); + if (!table || !table->numIndexes) + { + HeapFree(GetProcessHeap(), 0, table); + return ERROR_NO_DATA; + } + total_size = 0; + for (i = 0; i < table->numIndexes; i++) + { + size = 0; + if ((ret = adapterAddressesFromIndex(table->indexes[i], NULL, &size))) + { + HeapFree(GetProcessHeap(), 0, table); + return ret; + } + total_size += size; + } + if (aa && *buflen >= total_size) + { + ULONG bytes_left = size = total_size; + for (i = 0; i < table->numIndexes; i++) + { + if ((ret = adapterAddressesFromIndex(table->indexes[i], aa, &size))) + { + HeapFree(GetProcessHeap(), 0, table); + return ret; + } + if (i < table->numIndexes - 1) + { + aa->Next = (IP_ADAPTER_ADDRESSES *)((char *)aa + size); + aa = aa->Next; + size = bytes_left -= size; + } + } + ret = ERROR_SUCCESS; + } + if (*buflen < total_size) ret = ERROR_BUFFER_OVERFLOW; + *buflen = total_size; + + TRACE("num adapters %u\n", table->numIndexes); + HeapFree(GetProcessHeap(), 0, table); + return ret; +} /****************************************************************** * GetBestInterface (IPHLPAPI.@) diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 2fc5e0d374e..f879c93a943 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -63,6 +63,7 @@ typedef DWORD (WINAPI *GetUdpStatisticsFunc)(PMIB_UDPSTATS); typedef DWORD (WINAPI *GetTcpTableFunc)(PMIB_TCPTABLE,PDWORD,BOOL); typedef DWORD (WINAPI *GetUdpTableFunc)(PMIB_UDPTABLE,PDWORD,BOOL); typedef DWORD (WINAPI *GetPerAdapterInfoFunc)(ULONG,PIP_PER_ADAPTER_INFO,PULONG); +typedef DWORD (WINAPI *GetAdaptersAddressesFunc)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); static GetNumberOfInterfacesFunc gGetNumberOfInterfaces = NULL; static GetIpAddrTableFunc gGetIpAddrTable = NULL; @@ -81,6 +82,7 @@ static GetUdpStatisticsFunc gGetUdpStatistics = NULL; static GetTcpTableFunc gGetTcpTable = NULL; static GetUdpTableFunc gGetUdpTable = NULL; static GetPerAdapterInfoFunc gGetPerAdapterInfo = NULL; +static GetAdaptersAddressesFunc gGetAdaptersAddresses = NULL; static void loadIPHlpApi(void) { @@ -119,6 +121,7 @@ static void loadIPHlpApi(void) gGetUdpTable = (GetUdpTableFunc)GetProcAddress( hLibrary, "GetUdpTable"); gGetPerAdapterInfo = (GetPerAdapterInfoFunc)GetProcAddress(hLibrary, "GetPerAdapterInfo"); + gGetAdaptersAddresses = (GetAdaptersAddressesFunc)GetProcAddress(hLibrary, "GetAdaptersAddresses"); } } @@ -811,6 +814,71 @@ static void testWin2KFunctions(void) testGetPerAdapterInfo(); } +static void test_GetAdaptersAddresses(void) +{ + ULONG ret, size; + IP_ADAPTER_ADDRESSES *aa; + IP_ADAPTER_UNICAST_ADDRESS *ua; + + if (!gGetAdaptersAddresses) + { + win_skip("GetAdaptersAddresses not present\n"); + return; + } + + ret = gGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", ret); + + ret = gGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size); + ok(ret == ERROR_BUFFER_OVERFLOW, "expected ERROR_BUFFER_OVERFLOW, got %u\n", ret); + if (ret != ERROR_BUFFER_OVERFLOW) return; + + aa = HeapAlloc(GetProcessHeap(), 0, size); + ret = gGetAdaptersAddresses(AF_UNSPEC, 0, NULL, aa, &size); + ok(!ret, "expected ERROR_SUCCESS got %u\n", ret); + + while (!ret && winetest_debug > 1 && aa) + { + trace("Length: %u\n", aa->Length); + trace("IfIndex: %u\n", aa->IfIndex); + trace("Next: %p\n", aa->Next); + trace("AdapterName: %s\n", aa->AdapterName); + trace("FirstUnicastAddress: %p\n", aa->FirstUnicastAddress); + ua = aa->FirstUnicastAddress; + while (ua) + { + trace("\tLength: %u\n", ua->Length); + trace("\tFlags: 0x%08x\n", ua->Flags); + trace("\tNext: %p\n", ua->Next); + trace("\tAddress.lpSockaddr: %p\n", ua->Address.lpSockaddr); + trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength); + trace("\tPrefixOrigin: %u\n", ua->PrefixOrigin); + trace("\tSuffixOrigin: %u\n", ua->SuffixOrigin); + trace("\tDadState: %u\n", ua->DadState); + trace("\tValidLifetime: 0x%08x\n", ua->ValidLifetime); + trace("\tPreferredLifetime: 0x%08x\n", ua->PreferredLifetime); + trace("\tLeaseLifetime: 0x%08x\n", ua->LeaseLifetime); + trace("\n"); + ua = ua->Next; + } + trace("FirstAnycastAddress: %p\n", aa->FirstAnycastAddress); + trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress); + trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress); + trace("DnsSuffix: %p\n", aa->DnsSuffix); + trace("Description: %p\n", aa->Description); + trace("FriendlyName: %p\n", aa->FriendlyName); + trace("PhysicalAddress: %02x\n", aa->PhysicalAddress[0]); + trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength); + trace("Flags: 0x%08x\n", aa->Flags); + trace("Mtu: %u\n", aa->Mtu); + trace("IfType: %u\n", aa->IfType); + trace("OperStatus: %u\n", aa->OperStatus); + trace("\n"); + aa = aa->Next; + } + HeapFree(GetProcessHeap(), 0, aa); +} + START_TEST(iphlpapi) { @@ -820,6 +888,7 @@ START_TEST(iphlpapi) testWinNT4Functions(); testWin98Functions(); testWin2KFunctions(); + test_GetAdaptersAddresses(); freeIPHlpApi(); } } diff --git a/dlls/kernel32/editline.c b/dlls/kernel32/editline.c index 6fab049a72f..ab709168879 100644 --- a/dlls/kernel32/editline.c +++ b/dlls/kernel32/editline.c @@ -656,13 +656,6 @@ static const KeyEntry StdKeyMap[] = { 0, NULL } }; -static const KeyEntry Win32ExtraStdKeyMap[] = -{ - {/*VK_F8*/ 0x77, WCEL_FindPrevInHist }, - { 0, NULL } -}; - - static const KeyEntry EmacsKeyMapCtrl[] = { { CTRL('@'), WCEL_SetMark }, @@ -712,9 +705,8 @@ static const KeyEntry EmacsKeyMapAlt[] = { 0, NULL } }; -static const KeyEntry EmacsKeyMapExtended[] = +static const KeyEntry EmacsStdKeyMap[] = { - {/*RETURN*/ 0x0d, WCEL_Done }, {/*VK_PRIOR*/0x21, WCEL_MoveToPrevHist }, {/*VK_NEXT*/ 0x22, WCEL_MoveToNextHist }, {/*VK_END*/ 0x23, WCEL_MoveToEnd }, @@ -727,16 +719,16 @@ static const KeyEntry EmacsKeyMapExtended[] = static const KeyMap EmacsKeyMap[] = { - {0x00000000, 1, StdKeyMap}, - {0x00000001, 1, EmacsKeyMapAlt}, /* left alt */ - {0x00000002, 1, EmacsKeyMapAlt}, /* right alt */ - {0x00000004, 1, EmacsKeyMapCtrl}, /* left ctrl */ - {0x00000008, 1, EmacsKeyMapCtrl}, /* right ctrl */ - {0x00000100, 0, EmacsKeyMapExtended}, - {0, 0, 0} + {0, 1, StdKeyMap}, + {0, 0, EmacsStdKeyMap}, + {RIGHT_ALT_PRESSED, 1, EmacsKeyMapAlt}, /* right alt */ + {LEFT_ALT_PRESSED, 1, EmacsKeyMapAlt}, /* left alt */ + {RIGHT_CTRL_PRESSED, 1, EmacsKeyMapCtrl}, /* right ctrl */ + {LEFT_CTRL_PRESSED, 1, EmacsKeyMapCtrl}, /* left ctrl */ + {0, 0, NULL} }; -static const KeyEntry Win32KeyMapExtended[] = +static const KeyEntry Win32StdKeyMap[] = { {/*VK_LEFT*/ 0x25, WCEL_MoveLeft }, {/*VK_RIGHT*/0x27, WCEL_MoveRight }, @@ -745,10 +737,11 @@ static const KeyEntry Win32KeyMapExtended[] = {/*VK_UP*/ 0x26, WCEL_MoveToPrevHist }, {/*VK_DOWN*/ 0x28, WCEL_MoveToNextHist }, {/*VK_DEL*/ 0x2e, WCEL_DeleteCurrChar }, + {/*VK_F8*/ 0x77, WCEL_FindPrevInHist }, { 0, NULL } }; -static const KeyEntry Win32KeyMapCtrlExtended[] = +static const KeyEntry Win32KeyMapCtrl[] = { {/*VK_LEFT*/ 0x25, WCEL_MoveToLeftWord }, {/*VK_RIGHT*/0x27, WCEL_MoveToRightWord }, @@ -758,12 +751,11 @@ static const KeyEntry Win32KeyMapCtrlExtended[] = static const KeyMap Win32KeyMap[] = { - {0x00000000, 1, StdKeyMap}, - {0x00000000, 0, Win32ExtraStdKeyMap}, - {0x00000100, 0, Win32KeyMapExtended}, - {0x00000104, 0, Win32KeyMapCtrlExtended}, - {0x00000108, 0, Win32KeyMapCtrlExtended}, - {0, 0, 0} + {0, 1, StdKeyMap}, + {0, 0, Win32StdKeyMap}, + {RIGHT_CTRL_PRESSED, 0, Win32KeyMapCtrl}, + {LEFT_CTRL_PRESSED, 0, Win32KeyMapCtrl}, + {0, 0, NULL} }; #undef CTRL diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 39efde9811d..a674e074965 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -34,7 +34,30 @@ static SIZE_T resize_9x(SIZE_T size) return max(dwSizeAligned, 12); /* at least 12 bytes */ } -START_TEST(heap) +static void test_sized_HeapAlloc(int nbytes) +{ + int success; + char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes); + ok(buf != NULL, "allocate failed"); + ok(buf[0] == 0, "buffer not zeroed"); + success = HeapFree(GetProcessHeap(), 0, buf); + ok(success, "free failed"); +} + +static void test_sized_HeapReAlloc(int nbytes1, int nbytes2) +{ + int success; + char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes1); + ok(buf != NULL, "allocate failed"); + ok(buf[0] == 0, "buffer not zeroed"); + buf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf, nbytes2); + ok(buf != NULL, "reallocate failed"); + ok(buf[nbytes2-1] == 0, "buffer not zeroed"); + success = HeapFree(GetProcessHeap(), 0, buf); + ok(success, "free failed"); +} + +static void test_heap(void) { LPVOID mem; LPVOID msecond; @@ -338,3 +361,16 @@ START_TEST(heap) GlobalFree(gbl); } + +START_TEST(heap) +{ + test_heap(); + + /* Test both short and very long blocks */ + test_sized_HeapAlloc(1); + test_sized_HeapAlloc(1 << 20); + test_sized_HeapReAlloc(1, 100); + test_sized_HeapReAlloc(1, (1 << 20)); + test_sized_HeapReAlloc((1 << 20), (2 << 20)); + test_sized_HeapReAlloc((1 << 20), 1); +} diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 97e3559c000..19fc6f08f7d 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -20,6 +20,7 @@ #include "wine/test.h" #include "winbase.h" +#include static HINSTANCE hdll; static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD); @@ -29,29 +30,51 @@ static BOOL (WINAPI *pFindNextVolumeA)(HANDLE,LPSTR,DWORD); static BOOL (WINAPI *pFindVolumeClose)(HANDLE); static UINT (WINAPI *pGetLogicalDriveStringsA)(UINT,LPSTR); static UINT (WINAPI *pGetLogicalDriveStringsW)(UINT,LPWSTR); +static BOOL (WINAPI *pGetVolumeInformationA)(LPCSTR, LPSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPSTR, DWORD); /* ############################### */ static void test_query_dos_deviceA(void) { char drivestr[] = "a:"; - char *p, buffer[2000]; - DWORD ret; + char *p, *buffer, buffer2[2000]; + DWORD ret, ret2, buflen=32768; BOOL found = FALSE; if (!pFindFirstVolumeA) { - skip("On win9x, HARDDISK and RAMDISK not present\n"); + win_skip("On win9x, HARDDISK and RAMDISK not present\n"); return; } + buffer = HeapAlloc( GetProcessHeap(), 0, buflen ); + ret = QueryDosDeviceA( NULL, buffer, buflen ); + ok(ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER, + "QueryDosDevice buffer too small\n"); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + HeapFree( GetProcessHeap(), 0, buffer ); + return; + } + ok(ret, "QueryDosDeviceA failed to return list, last error %u\n", GetLastError()); + if (ret) { + p = buffer; + for (;;) { + if (!strlen(p)) break; + ret2 = QueryDosDeviceA( p, buffer2, sizeof(buffer2) ); + ok(ret2, "QueryDosDeviceA failed to return current mapping for %s, last error %u\n", p, GetLastError()); + p += strlen(p) + 1; + if (ret <= (p-buffer)) break; + } + } + for (;drivestr[0] <= 'z'; drivestr[0]++) { - ret = QueryDosDeviceA( drivestr, buffer, sizeof(buffer)); + ret = QueryDosDeviceA( drivestr, buffer, buflen); if(ret) { for (p = buffer; *p; p++) *p = toupper(*p); if (strstr(buffer, "HARDDISK") || strstr(buffer, "RAMDISK")) found = TRUE; } } ok(found, "expected at least one devicename to contain HARDDISK or RAMDISK\n"); + HeapFree( GetProcessHeap(), 0, buffer ); } static void test_FindFirstVolume(void) @@ -216,6 +239,130 @@ static void test_GetLogicalDriveStringsW(void) HeapFree(GetProcessHeap(), 0, buf); } +static void test_GetVolumeInformationA(void) +{ + BOOL ret; + UINT result; + char Root_Dir0[]="C:"; + char Root_Dir1[]="C:\\"; + char Root_Dir2[]="\\\\?\\C:\\"; + char volume[MAX_PATH+1]; + DWORD vol_name_size=MAX_PATH+1, vol_serial_num=-1, max_comp_len=0, fs_flags=0, fs_name_len=MAX_PATH+1; + char vol_name_buf[MAX_PATH+1], fs_name_buf[MAX_PATH+1]; + char windowsdir[MAX_PATH+10]; + + if (!pGetVolumeInformationA) { + win_skip("GetVolumeInformationA not found\n"); + return; + } + if (!pGetVolumeNameForVolumeMountPointA) { + win_skip("GetVolumeNameForVolumeMountPointA not found\n"); + return; + } + + /* get windows drive letter and update strings for testing */ + result = GetWindowsDirectory(windowsdir, sizeof(windowsdir)); + ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n"); + ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError()); + Root_Dir0[0] = windowsdir[0]; + Root_Dir1[0] = windowsdir[0]; + Root_Dir2[4] = windowsdir[0]; + + /* get the unique volume name for the windows drive */ + ret = pGetVolumeNameForVolumeMountPointA(Root_Dir1, volume, MAX_PATH); + ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n"); + + /* **** now start the tests **** */ + /* check for error on no trailing \ */ + ret = pGetVolumeInformationA(Root_Dir0, vol_name_buf, vol_name_size, NULL, + NULL, NULL, fs_name_buf, fs_name_len); + ok(!ret && GetLastError() == ERROR_INVALID_NAME, + "GetVolumeInformationA w/o '\\' did not fail, last error %u\n", GetLastError()); + + /* try null root directory to return "root of the current directory" */ + ret = pGetVolumeInformationA(NULL, vol_name_buf, vol_name_size, NULL, + NULL, NULL, fs_name_buf, fs_name_len); + ok(ret, "GetVolumeInformationA failed on null root dir, last error %u\n", GetLastError()); + + /* Try normal drive letter with trailing \ */ + ret = pGetVolumeInformationA(Root_Dir1, vol_name_buf, vol_name_size, + &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); + ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir1, GetLastError()); + + /* try again with dirve letter and the "disable parsing" prefix */ + ret = pGetVolumeInformationA(Root_Dir2, vol_name_buf, vol_name_size, + &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); + todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir2, GetLastError()); + + /* try again with unique voluem name */ + ret = pGetVolumeInformationA(volume, vol_name_buf, vol_name_size, + &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); + todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", volume, GetLastError()); + + /* try again with device name space */ + Root_Dir2[2] = '.'; + ret = pGetVolumeInformationA(Root_Dir2, vol_name_buf, vol_name_size, + &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); + todo_wine ok(ret, "GetVolumeInformationA failed, root=%s, last error=%u\n", Root_Dir2, GetLastError()); + + /* try again with a directory off the root - should generate error */ + if (windowsdir[strlen(windowsdir)-1] != '\\') strcat(windowsdir, "\\"); + ret = pGetVolumeInformationA(windowsdir, vol_name_buf, vol_name_size, + &vol_serial_num, &max_comp_len, &fs_flags, fs_name_buf, fs_name_len); + todo_wine ok(!ret && GetLastError()==ERROR_DIR_NOT_ROOT, + "GetVolumeInformationA failed, root=%s, last error=%u\n", windowsdir, GetLastError()); +} + +/* Test to check that unique volume name from windows dir mount point */ +/* matches at least one of the unique volume names returned from the */ +/* FindFirstVolumeA/FindNextVolumeA list. */ +static void test_enum_vols(void) +{ + DWORD ret; + HANDLE hFind = INVALID_HANDLE_VALUE; + char Volume_1[MAX_PATH] = {0}; + char Volume_2[MAX_PATH] = {0}; + char path[] = "c:\\"; + BOOL found = FALSE; + char windowsdir[MAX_PATH]; + + if (!pGetVolumeNameForVolumeMountPointA) { + win_skip("GetVolumeNameForVolumeMountPointA not found\n"); + return; + } + + /*get windows drive letter and update strings for testing */ + ret = GetWindowsDirectory( windowsdir, sizeof(windowsdir) ); + ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n"); + ok(ret != 0, "GetWindowsDirecory: error %d\n", GetLastError()); + path[0] = windowsdir[0]; + + /* get the unique volume name for the windows drive */ + ret = pGetVolumeNameForVolumeMountPointA( path, Volume_1, MAX_PATH ); + ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n"); +todo_wine + ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name %s\n", Volume_1); + + /* get first unique volume name of list */ + hFind = pFindFirstVolumeA( Volume_2, MAX_PATH ); + ok(hFind != INVALID_HANDLE_VALUE, "FindFirstVolume failed, err=%u\n", + GetLastError()); + + do + { + /* validate correct length of unique volume name */ + ok(strlen(Volume_2) == 49, "Find[First/Next]Volume returned wrong length name %s\n", Volume_1); + if (memcmp(Volume_1, Volume_2, 49) == 0) + { + found = TRUE; + break; + } + } while (pFindNextVolumeA( hFind, Volume_2, MAX_PATH )); +todo_wine + ok(found, "volume name %s not found by Find[First/Next]Volume\n", Volume_1); + pFindVolumeClose( hFind ); +} + START_TEST(volume) { hdll = GetModuleHandleA("kernel32.dll"); @@ -226,6 +373,7 @@ START_TEST(volume) pFindVolumeClose = (void *) GetProcAddress(hdll, "FindVolumeClose"); pGetLogicalDriveStringsA = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsA"); pGetLogicalDriveStringsW = (void *) GetProcAddress(hdll, "GetLogicalDriveStringsW"); + pGetVolumeInformationA = (void *) GetProcAddress(hdll, "GetVolumeInformationA"); test_query_dos_deviceA(); test_FindFirstVolume(); @@ -233,4 +381,6 @@ START_TEST(volume) test_GetVolumeNameForVolumeMountPointW(); test_GetLogicalDriveStringsA(); test_GetLogicalDriveStringsW(); + test_GetVolumeInformationA(); + test_enum_vols(); } diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c index 31490b90db0..1b44aced0bb 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c @@ -511,8 +511,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len, static const WCHAR audiocdW[] = {'A','u','d','i','o',' ','C','D',0}; static const WCHAR fatW[] = {'F','A','T',0}; static const WCHAR fat32W[] = {'F','A','T','3','2',0}; + static const WCHAR ntfsW[] = {'N','T','F','S',0}; static const WCHAR cdfsW[] = {'C','D','F','S',0}; - static const WCHAR unixfsW[] = {'U','N','I','X','F','S',0}; WCHAR device[] = {'\\','\\','.','\\','A',':',0}; HANDLE handle; @@ -526,7 +526,7 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len, } else { - if (!root[0] || root[1] != ':') + if (!root[0] || root[1] != ':' || root[lstrlenW(root)-1] != '\\' ) { SetLastError( ERROR_INVALID_NAME ); return FALSE; @@ -613,7 +613,7 @@ fill_fs_info: /* now fill in the information that depends on the file system ty if (flags) *flags = FILE_CASE_PRESERVED_NAMES; /* FIXME */ break; default: - if (fsname) lstrcpynW( fsname, unixfsW, fsname_len ); + if (fsname) lstrcpynW( fsname, ntfsW, fsname_len ); if (filename_len) *filename_len = 255; if (flags) *flags = FILE_CASE_PRESERVED_NAMES; break; diff --git a/dlls/mciqtz32/mciqtz.c b/dlls/mciqtz32/mciqtz.c index 0435a11f07c..837122747c7 100644 --- a/dlls/mciqtz32/mciqtz.c +++ b/dlls/mciqtz32/mciqtz.c @@ -338,6 +338,110 @@ static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa } /*************************************************************************** + * MCIQTZ_mciGetDevCaps [internal] + */ +static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms) +{ + WINE_MCIQTZ* wma; + + TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); + + if (!lpParms) + return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIQTZ_mciGetOpenDev(wDevID); + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + + if (!(dwFlags & MCI_STATUS_ITEM)) { + WARN("No capability item specified\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + + switch (lpParms->dwItem) { + case MCI_GETDEVCAPS_CAN_RECORD: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_GETDEVCAPS_CAN_RECORD = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_HAS_AUDIO: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + TRACE("MCI_GETDEVCAPS_HAS_AUDIO = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_HAS_VIDEO: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + TRACE("MCI_GETDEVCAPS_HAS_VIDEO = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_DEVICE_TYPE: + lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_DIGITAL_VIDEO, MCI_DEVTYPE_DIGITAL_VIDEO); + TRACE("MCI_GETDEVCAPS_DEVICE_TYPE = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_USES_FILES: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + TRACE("MCI_GETDEVCAPS_USES_FILES = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_COMPOUND_DEVICE: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_CAN_EJECT: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_GETDEVCAPS_EJECT = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_CAN_PLAY: + lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE); + TRACE("MCI_GETDEVCAPS_CAN_PLAY = %08x\n", lpParms->dwReturn); + break; + case MCI_GETDEVCAPS_CAN_SAVE: + lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); + TRACE("MCI_GETDEVCAPS_CAN_SAVE = %08x\n", lpParms->dwReturn); + break; + default: + ERR("Unknown capability %08x\n", lpParms->dwItem); + return MCIERR_UNRECOGNIZED_COMMAND; + } + + return MCI_RESOURCE_RETURNED; +} + +/*************************************************************************** + * MCIQTZ_mciSet [internal] + */ +static DWORD MCIQTZ_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms) +{ + WINE_MCIQTZ* wma; + + TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); + + if (!lpParms) + return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIQTZ_mciGetOpenDev(wDevID); + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + + if (dwFlags & MCI_SET_TIME_FORMAT) { + switch (lpParms->dwTimeFormat) { + case MCI_FORMAT_MILLISECONDS: + TRACE("MCI_SET_TIME_FORMAT = MCI_FORMAT_MILLISECONDS\n"); + wma->time_format = MCI_FORMAT_MILLISECONDS; + break; + case MCI_FORMAT_FRAMES: + TRACE("MCI_SET_TIME_FORMAT = MCI_FORMAT_FRAMES\n"); + wma->time_format = MCI_FORMAT_FRAMES; + break; + default: + WARN("Bad time format %u\n", lpParms->dwTimeFormat); + return MCIERR_BAD_TIME_FORMAT; + } + } + + if (dwFlags & ~MCI_SET_TIME_FORMAT) + FIXME("Flags not supported yet %08lX\n", dwFlags & ~MCI_SET_TIME_FORMAT); + + return 0; +} + +/*************************************************************************** * MCIQTZ_mciStatus [internal] */ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpParms) @@ -415,6 +519,90 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS return 0; } +/*************************************************************************** + * MCIQTZ_mciWhere [internal] + */ +static DWORD MCIQTZ_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms) +{ + WINE_MCIQTZ* wma; + IVideoWindow* pVideoWindow; + HRESULT hr; + HWND hWnd; + RECT rc; + + TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); + + if (!lpParms) + return MCIERR_NULL_PARAMETER_BLOCK; + + wma = MCIQTZ_mciGetOpenDev(wDevID); + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + + /* Find if there is a video stream and get the display window */ + hr = IGraphBuilder_QueryInterface(wma->pgraph, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (FAILED(hr)) { + ERR("Cannot get IVideoWindow interface (hr = %x)\n", hr); + return MCIERR_INTERNAL; + } + + hr = IVideoWindow_get_Owner(pVideoWindow, (OAHWND*)&hWnd); + IVideoWindow_Release(pVideoWindow); + if (FAILED(hr)) { + TRACE("No video stream, returning no window error\n"); + return MCIERR_NO_WINDOW; + } + + if (dwFlags & MCI_DGV_WHERE_SOURCE) { + if (dwFlags & MCI_DGV_WHERE_MAX) + FIXME("MCI_DGV_WHERE_SOURCE_MAX not supported yet\n"); + else + FIXME("MCI_DGV_WHERE_SOURCE not supported yet\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + if (dwFlags & MCI_DGV_WHERE_DESTINATION) { + if (dwFlags & MCI_DGV_WHERE_MAX) { + GetClientRect(hWnd, &rc); + TRACE("MCI_DGV_WHERE_DESTINATION_MAX %s\n", wine_dbgstr_rect(&rc)); + } else { + FIXME("MCI_DGV_WHERE_DESTINATION not supported yet\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + } + if (dwFlags & MCI_DGV_WHERE_FRAME) { + if (dwFlags & MCI_DGV_WHERE_MAX) + FIXME("MCI_DGV_WHERE_FRAME_MAX not supported yet\n"); + else + FIXME("MCI_DGV_WHERE_FRAME not supported yet\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + if (dwFlags & MCI_DGV_WHERE_VIDEO) { + if (dwFlags & MCI_DGV_WHERE_MAX) + FIXME("MCI_DGV_WHERE_VIDEO_MAX not supported yet\n"); + else + FIXME("MCI_DGV_WHERE_VIDEO not supported yet\n"); + return MCIERR_UNRECOGNIZED_COMMAND; + } + if (dwFlags & MCI_DGV_WHERE_WINDOW) { + if (dwFlags & MCI_DGV_WHERE_MAX) { + GetWindowRect(GetDesktopWindow(), &rc); + TRACE("MCI_DGV_WHERE_WINDOW_MAX %s\n", wine_dbgstr_rect(&rc)); + } else { + GetWindowRect(hWnd, &rc); + TRACE("MCI_DGV_WHERE_WINDOW %s\n", wine_dbgstr_rect(&rc)); + } + } + + /* In MCI, RECT structure is used differently: rc.right = width & rc.bottom = height + * So convert the normal RECT into a MCI RECT before returning */ + lpParms->rc.left = rc.left; + lpParms->rc.top = rc.right; + lpParms->rc.right = rc.right - rc.left; + lpParms->rc.bottom = rc.bottom - rc.top; + + return 0; +} + /*======================================================================* * MCI QTZ entry points * *======================================================================*/ @@ -451,12 +639,13 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_PLAY: return MCIQTZ_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); case MCI_SEEK: return MCIQTZ_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2); case MCI_STOP: return MCIQTZ_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); + case MCI_GETDEVCAPS: return MCIQTZ_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2); + case MCI_SET: return MCIQTZ_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2); case MCI_STATUS: return MCIQTZ_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2); + case MCI_WHERE: return MCIQTZ_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2); case MCI_RECORD: - case MCI_SET: case MCI_PAUSE: case MCI_RESUME: - case MCI_GETDEVCAPS: case MCI_INFO: case MCI_PUT: case MCI_WINDOW: @@ -466,7 +655,6 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_REALIZE: case MCI_UNFREEZE: case MCI_UPDATE: - case MCI_WHERE: case MCI_STEP: case MCI_COPY: case MCI_CUT: diff --git a/dlls/mciqtz32/mciqtz_private.h b/dlls/mciqtz32/mciqtz_private.h index 23945a4ff5c..dcfcad0eb4a 100644 --- a/dlls/mciqtz32/mciqtz_private.h +++ b/dlls/mciqtz32/mciqtz_private.h @@ -31,6 +31,7 @@ typedef struct { IGraphBuilder* pgraph; IMediaControl* pmctrl; BOOL started; + DWORD time_format; } WINE_MCIQTZ; #endif /* __WINE_PRIVATE_MCIQTZ_H */ diff --git a/dlls/mscoree/mscoree.spec b/dlls/mscoree/mscoree.spec index 03fbc1c532e..04b5e1cda9c 100644 --- a/dlls/mscoree/mscoree.spec +++ b/dlls/mscoree/mscoree.spec @@ -103,8 +103,8 @@ @ stub StrongNameSignatureGeneration @ stub StrongNameSignatureGenerationEx @ stub StrongNameSignatureSize -@ stub StrongNameSignatureVerification -@ stub StrongNameSignatureVerificationEx +@ stdcall StrongNameSignatureVerification(wstr long ptr) +@ stdcall StrongNameSignatureVerificationEx(wstr long ptr) @ stub StrongNameSignatureVerificationFromImage @ stub StrongNameTokenFromAssembly @ stub StrongNameTokenFromAssemblyEx diff --git a/dlls/mscoree/mscoree_main.c b/dlls/mscoree/mscoree_main.c index 386f4f76707..5b45adbe29a 100644 --- a/dlls/mscoree/mscoree_main.c +++ b/dlls/mscoree/mscoree_main.c @@ -324,6 +324,18 @@ HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID return E_NOTIMPL; } +BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags) +{ + FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags); + return FALSE; +} + +BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerification, BOOL* pVerified) +{ + FIXME("(%s, %u, %p): stub\n", debugstr_w(filename), forceVerification, pVerified); + return FALSE; +} + HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { FIXME("(%p, %p, %p): stub\n", rclsid, riid, ppv); diff --git a/dlls/mshtml/main.c b/dlls/mshtml/main.c index b1c8756ee99..aed4d76b34d 100644 --- a/dlls/mshtml/main.c +++ b/dlls/mshtml/main.c @@ -284,7 +284,6 @@ DEFINE_GUID(CLSID_HTMLPluginDocument, 0x25336921, 0x03F9, 0x11CF, 0x8F,0xD0, 0x0 DEFINE_GUID(CLSID_HTMLPopup, 0x3050F667, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_HTMLPopupDoc, 0x3050F67D, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_HTMLServerDoc, 0x3050F4E7, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); -DEFINE_GUID(CLSID_HTMLWindowProxy, 0x3050F391, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_IImageDecodeFilter, 0x607FD4E8, 0x0A03, 0x11D1, 0xAB,0x1D, 0x00,0xC0,0x4F,0xC9,0xB3,0x04); DEFINE_GUID(CLSID_IImgCtx, 0x3050F3D6, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_IntDitherer, 0x05F6FE1A, 0xECEF, 0x11D0, 0xAA,0xE7, 0x00,0xC0,0x4F,0xC9,0xB3,0x04); diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 90c7ba6c5d8..bee45b0de48 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -407,7 +407,7 @@ UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath, return ERROR_CALL_NOT_IMPLEMENTED; } -UINT MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid, +UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo) { FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_a(szProductCode), @@ -416,7 +416,7 @@ UINT MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid, return ERROR_CALL_NOT_IMPLEMENTED; } -UINT MsiDeterminePatchSequenceW(LPCWSTR szProductCode, LPCWSTR szUserSid, +UINT WINAPI MsiDeterminePatchSequenceW(LPCWSTR szProductCode, LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo) { FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_w(szProductCode), diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y index d71c1861ccc..8f241b155d2 100644 --- a/dlls/msi/sql.y +++ b/dlls/msi/sql.y @@ -359,15 +359,15 @@ data_type: } | TK_LONGCHAR { - $$ = 2; + $$ = MSITYPE_STRING | 0x400; } | TK_SHORT { - $$ = 2; + $$ = 2 | 0x400; } | TK_INT { - $$ = 2; + $$ = 2 | 0x400; } | TK_LONG { diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index b2c7d06c88f..41f65f18498 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -1128,7 +1128,14 @@ static void test_viewgetcolumninfo(void) r = run_query( hdb, 0, "CREATE TABLE `Properties` " - "( `Property` CHAR(255), `Value` CHAR(1) PRIMARY KEY `Property`)" ); + "( `Property` CHAR(255), " + " `Value` CHAR(1), " + " `Intvalue` INT, " + " `Integervalue` INTEGER, " + " `Shortvalue` SHORT, " + " `Longvalue` LONG, " + " `Longcharvalue` LONGCHAR " + " PRIMARY KEY `Property`)" ); ok( r == ERROR_SUCCESS , "Failed to create table\n" ); /* check the column types */ @@ -1137,12 +1144,22 @@ static void test_viewgetcolumninfo(void) ok( check_record( rec, 1, "S255"), "wrong record type\n"); ok( check_record( rec, 2, "S1"), "wrong record type\n"); + ok( check_record( rec, 3, "I2"), "wrong record type\n"); + ok( check_record( rec, 4, "I2"), "wrong record type\n"); + ok( check_record( rec, 5, "I2"), "wrong record type\n"); + ok( check_record( rec, 6, "I4"), "wrong record type\n"); + ok( check_record( rec, 7, "S0"), "wrong record type\n"); MsiCloseHandle( rec ); /* check the type in _Columns */ ok( 0x3dff == get_columns_table_type(hdb, "Properties", 1 ), "_columns table wrong\n"); ok( 0x1d01 == get_columns_table_type(hdb, "Properties", 2 ), "_columns table wrong\n"); + ok( 0x1502 == get_columns_table_type(hdb, "Properties", 3 ), "_columns table wrong\n"); + ok( 0x1502 == get_columns_table_type(hdb, "Properties", 4 ), "_columns table wrong\n"); + ok( 0x1502 == get_columns_table_type(hdb, "Properties", 5 ), "_columns table wrong\n"); + ok( 0x1104 == get_columns_table_type(hdb, "Properties", 6 ), "_columns table wrong\n"); + ok( 0x1d00 == get_columns_table_type(hdb, "Properties", 7 ), "_columns table wrong\n"); /* now try the names */ rec = get_column_info( hdb, "select * from `Properties`", MSICOLINFO_NAMES ); @@ -1150,6 +1167,11 @@ static void test_viewgetcolumninfo(void) ok( check_record( rec, 1, "Property"), "wrong record type\n"); ok( check_record( rec, 2, "Value"), "wrong record type\n"); + ok( check_record( rec, 3, "Intvalue"), "wrong record type\n"); + ok( check_record( rec, 4, "Integervalue"), "wrong record type\n"); + ok( check_record( rec, 5, "Shortvalue"), "wrong record type\n"); + ok( check_record( rec, 6, "Longvalue"), "wrong record type\n"); + ok( check_record( rec, 7, "Longcharvalue"), "wrong record type\n"); MsiCloseHandle( rec ); diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c index 1082486212d..b0d820815a1 100644 --- a/dlls/msvfw32/tests/msvfw.c +++ b/dlls/msvfw32/tests/msvfw.c @@ -51,6 +51,16 @@ static void test_OpenCase(void) if (h) { ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); } + h = ICOpen(mmioFOURCC('v','i','d','c'),mmioFOURCC('m','S','v','C'),ICMODE_DECOMPRESS); + ok(0!=h,"ICOpen(vidc.mSvC) failed\n"); + if (h) { + ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); + } + h = ICOpen(mmioFOURCC('v','I','d','C'),mmioFOURCC('m','s','v','c'),ICMODE_DECOMPRESS); + ok(0!=h,"ICOpen(vIdC.msvc) failed\n"); + if (h) { + ok(ICClose(h)==ICERR_OK,"ICClose failed\n"); + } } START_TEST(msvfw) diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 04996f3035e..5fe0c28deb0 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -40,13 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh); -/* Exception record for handling exceptions happening inside exception handlers */ -typedef struct -{ - EXCEPTION_REGISTRATION_RECORD frame; - EXCEPTION_REGISTRATION_RECORD *prevFrame; -} EXC_NESTED_FRAME; - typedef struct { struct list entry; @@ -64,82 +57,6 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = }; static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0, 0, 0 }; -#ifdef __i386__ -# define GET_IP(context) ((LPVOID)(context)->Eip) -#elif defined(__sparc__) -# define GET_IP(context) ((LPVOID)(context)->pc) -#elif defined(__powerpc__) -# define GET_IP(context) ((LPVOID)(context)->Iar) -#elif defined(__ALPHA__) -# define GET_IP(context) ((LPVOID)(context)->Fir) -#elif defined(__x86_64__) -# define GET_IP(context) ((LPVOID)(context)->Rip) -#else -# error You must define GET_IP for this CPU -#endif - -/******************************************************************* - * EXC_RaiseHandler - * - * Handler for exceptions happening inside a handler. - */ -static DWORD EXC_RaiseHandler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) -{ - if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) - return ExceptionContinueSearch; - /* We shouldn't get here so we store faulty frame in dispatcher */ - *dispatcher = ((EXC_NESTED_FRAME*)frame)->prevFrame; - return ExceptionNestedException; -} - - -/******************************************************************* - * EXC_UnwindHandler - * - * Handler for exceptions happening inside an unwind handler. - */ -static DWORD EXC_UnwindHandler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) -{ - if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) - return ExceptionContinueSearch; - /* We shouldn't get here so we store faulty frame in dispatcher */ - *dispatcher = ((EXC_NESTED_FRAME*)frame)->prevFrame; - return ExceptionCollidedUnwind; -} - - -/******************************************************************* - * EXC_CallHandler - * - * Call an exception handler, setting up an exception frame to catch exceptions - * happening during the handler execution. - * - * For i386 this function is implemented in assembler in signal_i386.c. - */ -#ifndef __i386__ -static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher, - PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nested_handler) -{ - EXC_NESTED_FRAME newframe; - DWORD ret; - - newframe.frame.Handler = nested_handler; - newframe.prevFrame = frame; - __wine_push_frame( &newframe.frame ); - ret = handler( record, frame, context, dispatcher ); - __wine_pop_frame( &newframe.frame ); - return ret; -} -#else -/* in signal_i386.c */ -extern DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame, - CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher, - PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nested_handler); -#endif - /********************************************************************** * wait_suspend * @@ -187,7 +104,7 @@ void wait_suspend( CONTEXT *context ) * * Send an EXCEPTION_DEBUG_EVENT event to the debugger. */ -static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context ) +NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context ) { NTSTATUS ret; DWORD i; @@ -236,7 +153,7 @@ static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTE * * Call the vectored handlers chain. */ -static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) { struct list *ptr; LONG ret = EXCEPTION_CONTINUE_SEARCH; @@ -260,156 +177,6 @@ static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) } -/********************************************************************** - * call_stack_handlers - * - * Call the stack handlers chain. - */ -static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) -{ - EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame; - DWORD res; - - frame = NtCurrentTeb()->Tib.ExceptionList; - nested_frame = NULL; - while (frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) - { - /* Check frame address */ - if (((void*)frame < NtCurrentTeb()->Tib.StackLimit) || - ((void*)(frame+1) > NtCurrentTeb()->Tib.StackBase) || - (ULONG_PTR)frame & 3) - { - rec->ExceptionFlags |= EH_STACK_INVALID; - break; - } - - /* Call handler */ - TRACE( "calling handler at %p code=%x flags=%x\n", - frame->Handler, rec->ExceptionCode, rec->ExceptionFlags ); - res = EXC_CallHandler( rec, frame, context, &dispatch, frame->Handler, EXC_RaiseHandler ); - TRACE( "handler at %p returned %x\n", frame->Handler, res ); - - if (frame == nested_frame) - { - /* no longer nested */ - nested_frame = NULL; - rec->ExceptionFlags &= ~EH_NESTED_CALL; - } - - switch(res) - { - case ExceptionContinueExecution: - if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS; - return STATUS_NONCONTINUABLE_EXCEPTION; - case ExceptionContinueSearch: - break; - case ExceptionNestedException: - if (nested_frame < dispatch) nested_frame = dispatch; - rec->ExceptionFlags |= EH_NESTED_CALL; - break; - default: - return STATUS_INVALID_DISPOSITION; - } - frame = frame->Prev; - } - return STATUS_UNHANDLED_EXCEPTION; -} - - -/******************************************************************* - * raise_exception - * - * Implementation of NtRaiseException. - */ -NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) -{ - NTSTATUS status; - - if (first_chance) - { - DWORD c; - - TRACE( "code=%x flags=%x addr=%p ip=%p tid=%04x\n", - rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, - GET_IP(context), GetCurrentThreadId() ); - for (c = 0; c < rec->NumberParameters; c++) - TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] ); - if (rec->ExceptionCode == EXCEPTION_WINE_STUB) - { - if (rec->ExceptionInformation[1] >> 16) - MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", - rec->ExceptionAddress, - (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); - else - MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", - rec->ExceptionAddress, - (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); - } - else - { -#ifdef __i386__ - TRACE(" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n", - context->Eax, context->Ebx, context->Ecx, - context->Edx, context->Esi, context->Edi ); - TRACE(" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x\n", - context->Ebp, context->Esp, context->SegCs, context->SegDs, - context->SegEs, context->SegFs, context->SegGs, context->EFlags ); -#elif defined(__x86_64__) - TRACE(" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", - context->Rax, context->Rbx, context->Rcx, context->Rdx ); - TRACE(" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", - context->Rsi, context->Rdi, context->Rbp, context->Rsp ); - TRACE(" r8=%016lx r9=%016lx r10=%016lx r11=%016lx\n", - context->R8, context->R9, context->R10, context->R11 ); - TRACE(" r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", - context->R12, context->R13, context->R14, context->R15 ); -#endif - } - status = send_debug_event( rec, TRUE, context ); - if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) - return STATUS_SUCCESS; - -#ifdef __i386__ - /* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */ - if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context->Eip--; -#endif - - if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) - return STATUS_SUCCESS; - - if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) - return status; - } - - /* last chance exception */ - - status = send_debug_event( rec, FALSE, context ); - if (status != DBG_CONTINUE) - { - if (rec->ExceptionFlags & EH_STACK_INVALID) - ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); - else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) - ERR("Process attempted to continue execution after noncontinuable exception.\n"); - else - ERR("Unhandled exception code %x flags %x addr %p\n", - rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); - NtTerminateProcess( NtCurrentProcess(), 1 ); - } - return STATUS_SUCCESS; -} - - -/******************************************************************* - * NtRaiseException (NTDLL.@) - */ -NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) -{ - NTSTATUS status = raise_exception( rec, context, first_chance ); - if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); - return status; -} - - /******************************************************************* * raise_status * @@ -427,84 +194,6 @@ void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) } -/******************************************************************* - * RtlUnwind (NTDLL.@) - */ -void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID unusedEip, - PEXCEPTION_RECORD pRecord, PVOID returnEax, CONTEXT *context ) -{ - EXCEPTION_RECORD record; - EXCEPTION_REGISTRATION_RECORD *frame, *dispatch; - DWORD res; - -#ifdef __i386__ - context->Eax = (DWORD)returnEax; -#endif - - /* build an exception record, if we do not have one */ - if (!pRecord) - { - record.ExceptionCode = STATUS_UNWIND; - record.ExceptionFlags = 0; - record.ExceptionRecord = NULL; - record.ExceptionAddress = GET_IP(context); - record.NumberParameters = 0; - pRecord = &record; - } - - pRecord->ExceptionFlags |= EH_UNWINDING | (pEndFrame ? 0 : EH_EXIT_UNWIND); - - TRACE( "code=%x flags=%x\n", pRecord->ExceptionCode, pRecord->ExceptionFlags ); - - /* get chain of exception frames */ - frame = NtCurrentTeb()->Tib.ExceptionList; - while ((frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) && (frame != pEndFrame)) - { - /* Check frame address */ - if (pEndFrame && (frame > pEndFrame)) - raise_status( STATUS_INVALID_UNWIND_TARGET, pRecord ); - - if (((void*)frame < NtCurrentTeb()->Tib.StackLimit) || - ((void*)(frame+1) > NtCurrentTeb()->Tib.StackBase) || - (UINT_PTR)frame & 3) - raise_status( STATUS_BAD_STACK, pRecord ); - - /* Call handler */ - TRACE( "calling handler at %p code=%x flags=%x\n", - frame->Handler, pRecord->ExceptionCode, pRecord->ExceptionFlags ); - res = EXC_CallHandler( pRecord, frame, context, &dispatch, frame->Handler, EXC_UnwindHandler ); - TRACE( "handler at %p returned %x\n", frame->Handler, res ); - - switch(res) - { - case ExceptionContinueSearch: - break; - case ExceptionCollidedUnwind: - frame = dispatch; - break; - default: - raise_status( STATUS_INVALID_DISPOSITION, pRecord ); - break; - } - frame = __wine_pop_frame( frame ); - } -} - -/**********************************************************************/ - -#ifdef DEFINE_REGS_ENTRYPOINT -DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) -#else -void WINAPI RtlUnwind( PVOID pEndFrame, PVOID unusedEip, - PEXCEPTION_RECORD pRecord, PVOID returnEax ) -{ - CONTEXT context; - RtlCaptureContext( &context ); - __regs_RtlUnwind( pEndFrame, unusedEip, pRecord, returnEax, &context ); -} -#endif - - /*********************************************************************** * RtlRaiseStatus (NTDLL.@) * diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 85dd19dddbf..a4fac224801 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1538,6 +1538,8 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size { if (!find_large_block( heapPtr, ptr )) goto error; if (!(ret = realloc_large_block( heapPtr, flags, ptr, size ))) goto oom; + notify_free( ptr ); + notify_alloc( ret, size, flags & HEAP_ZERO_MEMORY ); goto done; } if ((char *)pArena < (char *)subheap->base + subheap->headerSize) goto error; @@ -1554,7 +1556,9 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE && (flags & HEAP_GROWABLE)) { if (!(ret = allocate_large_block( heapPtr, flags, size ))) goto oom; + notify_alloc( ret, size, flags & HEAP_ZERO_MEMORY ); memcpy( ret, pArena + 1, oldActualSize ); + /* FIXME: free old memory here! */ goto done; } if ((pNext < (char *)subheap->base + subheap->size) && diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 6c88975d137..15df5d0706e 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -41,7 +41,8 @@ struct drive_info /* exceptions */ extern void wait_suspend( CONTEXT *context ); -extern NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ); +extern NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context ); +extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ); extern void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) DECLSPEC_NORETURN; extern void set_cpu_context( const CONTEXT *context ); extern void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags ); diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index b36b51ebe80..13896f655fd 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -465,6 +465,16 @@ enum i386_trap_code #endif }; +/* Exception record for handling exceptions happening inside exception handlers */ +typedef struct +{ + EXCEPTION_REGISTRATION_RECORD frame; + EXCEPTION_REGISTRATION_RECORD *prevFrame; +} EXC_NESTED_FRAME; + +extern DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher, + PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nested_handler ); /*********************************************************************** * dispatch_signal @@ -528,6 +538,164 @@ static inline TEB *get_current_teb(void) } +/******************************************************************* + * raise_handler + * + * Handler for exceptions happening inside a handler. + */ +static DWORD raise_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) + return ExceptionContinueSearch; + /* We shouldn't get here so we store faulty frame in dispatcher */ + *dispatcher = ((EXC_NESTED_FRAME*)frame)->prevFrame; + return ExceptionNestedException; +} + + +/******************************************************************* + * unwind_handler + * + * Handler for exceptions happening inside an unwind handler. + */ +static DWORD unwind_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) + return ExceptionContinueSearch; + /* We shouldn't get here so we store faulty frame in dispatcher */ + *dispatcher = ((EXC_NESTED_FRAME*)frame)->prevFrame; + return ExceptionCollidedUnwind; +} + + +/********************************************************************** + * call_stack_handlers + * + * Call the stack handlers chain. + */ +static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame; + DWORD res; + + frame = NtCurrentTeb()->Tib.ExceptionList; + nested_frame = NULL; + while (frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) + { + /* Check frame address */ + if (((void*)frame < NtCurrentTeb()->Tib.StackLimit) || + ((void*)(frame+1) > NtCurrentTeb()->Tib.StackBase) || + (ULONG_PTR)frame & 3) + { + rec->ExceptionFlags |= EH_STACK_INVALID; + break; + } + + /* Call handler */ + TRACE( "calling handler at %p code=%x flags=%x\n", + frame->Handler, rec->ExceptionCode, rec->ExceptionFlags ); + res = EXC_CallHandler( rec, frame, context, &dispatch, frame->Handler, raise_handler ); + TRACE( "handler at %p returned %x\n", frame->Handler, res ); + + if (frame == nested_frame) + { + /* no longer nested */ + nested_frame = NULL; + rec->ExceptionFlags &= ~EH_NESTED_CALL; + } + + switch(res) + { + case ExceptionContinueExecution: + if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS; + return STATUS_NONCONTINUABLE_EXCEPTION; + case ExceptionContinueSearch: + break; + case ExceptionNestedException: + if (nested_frame < dispatch) nested_frame = dispatch; + rec->ExceptionFlags |= EH_NESTED_CALL; + break; + default: + return STATUS_INVALID_DISPOSITION; + } + frame = frame->Prev; + } + return STATUS_UNHANDLED_EXCEPTION; +} + + +/******************************************************************* + * raise_exception + * + * Implementation of NtRaiseException. + */ +static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status; + + if (first_chance) + { + DWORD c; + + TRACE( "code=%x flags=%x addr=%p ip=%08x tid=%04x\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, + context->Eip, GetCurrentThreadId() ); + for (c = 0; c < rec->NumberParameters; c++) + TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] ); + if (rec->ExceptionCode == EXCEPTION_WINE_STUB) + { + if (rec->ExceptionInformation[1] >> 16) + MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); + else + MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); + } + else + { + TRACE(" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n", + context->Eax, context->Ebx, context->Ecx, + context->Edx, context->Esi, context->Edi ); + TRACE(" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x\n", + context->Ebp, context->Esp, context->SegCs, context->SegDs, + context->SegEs, context->SegFs, context->SegGs, context->EFlags ); + } + status = send_debug_event( rec, TRUE, context ); + if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) + return STATUS_SUCCESS; + + /* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */ + if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context->Eip--; + + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) + return STATUS_SUCCESS; + + if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) + return status; + } + + /* last chance exception */ + + status = send_debug_event( rec, FALSE, context ); + if (status != DBG_CONTINUE) + { + if (rec->ExceptionFlags & EH_STACK_INVALID) + WINE_ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); + else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) + WINE_ERR("Process attempted to continue execution after noncontinuable exception.\n"); + else + WINE_ERR("Unhandled exception code %x flags %x addr %p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + NtTerminateProcess( NtCurrentProcess(), 1 ); + } + return STATUS_SUCCESS; +} + + #ifdef __HAVE_VM86 /*********************************************************************** * save_vm86_context @@ -2008,6 +2176,80 @@ void __wine_enter_vm86( CONTEXT *context ) #endif /* __HAVE_VM86 */ +/******************************************************************* + * RtlUnwind (NTDLL.@) + */ +void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID targetIp, + PEXCEPTION_RECORD pRecord, PVOID retval, CONTEXT *context ) +{ + EXCEPTION_RECORD record; + EXCEPTION_REGISTRATION_RECORD *frame, *dispatch; + DWORD res; + + context->Eax = (DWORD)retval; + + /* build an exception record, if we do not have one */ + if (!pRecord) + { + record.ExceptionCode = STATUS_UNWIND; + record.ExceptionFlags = 0; + record.ExceptionRecord = NULL; + record.ExceptionAddress = (void *)context->Eip; + record.NumberParameters = 0; + pRecord = &record; + } + + pRecord->ExceptionFlags |= EH_UNWINDING | (pEndFrame ? 0 : EH_EXIT_UNWIND); + + TRACE( "code=%x flags=%x\n", pRecord->ExceptionCode, pRecord->ExceptionFlags ); + + /* get chain of exception frames */ + frame = NtCurrentTeb()->Tib.ExceptionList; + while ((frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) && (frame != pEndFrame)) + { + /* Check frame address */ + if (pEndFrame && (frame > pEndFrame)) + raise_status( STATUS_INVALID_UNWIND_TARGET, pRecord ); + + if (((void*)frame < NtCurrentTeb()->Tib.StackLimit) || + ((void*)(frame+1) > NtCurrentTeb()->Tib.StackBase) || + (UINT_PTR)frame & 3) + raise_status( STATUS_BAD_STACK, pRecord ); + + /* Call handler */ + TRACE( "calling handler at %p code=%x flags=%x\n", + frame->Handler, pRecord->ExceptionCode, pRecord->ExceptionFlags ); + res = EXC_CallHandler( pRecord, frame, context, &dispatch, frame->Handler, unwind_handler ); + TRACE( "handler at %p returned %x\n", frame->Handler, res ); + + switch(res) + { + case ExceptionContinueSearch: + break; + case ExceptionCollidedUnwind: + frame = dispatch; + break; + default: + raise_status( STATUS_INVALID_DISPOSITION, pRecord ); + break; + } + frame = __wine_pop_frame( frame ); + } +} +DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) + + +/******************************************************************* + * NtRaiseException (NTDLL.@) + */ +NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status = raise_exception( rec, context, first_chance ); + if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); + return status; +} + + /*********************************************************************** * RtlRaiseException (NTDLL.@) */ diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index f37fb7156c8..8b4438a7654 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -610,6 +610,89 @@ static inline DWORD get_fpu_code( const CONTEXT *context ) return EXCEPTION_FLT_INVALID_OPERATION; /* generic error */ } + +/********************************************************************** + * call_stack_handlers + * + * Call the stack handlers chain. + */ +static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + EXCEPTION_POINTERS ptrs; + + FIXME( "not implemented on PowerPC\n" ); + + /* hack: call unhandled exception filter directly */ + ptrs.ExceptionRecord = rec; + ptrs.ContextRecord = context; + unhandled_exception_filter( &ptrs ); + return STATUS_UNHANDLED_EXCEPTION; +} + + +/******************************************************************* + * raise_exception + * + * Implementation of NtRaiseException. + */ +static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status; + + if (first_chance) + { + DWORD c; + + TRACE( "code=%x flags=%x addr=%p ip=%x tid=%04x\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, + context->Iar, GetCurrentThreadId() ); + for (c = 0; c < rec->NumberParameters; c++) + TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] ); + if (rec->ExceptionCode == EXCEPTION_WINE_STUB) + { + if (rec->ExceptionInformation[1] >> 16) + MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); + else + MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); + } + else + { + /* FIXME: dump context */ + } + + status = send_debug_event( rec, TRUE, context ); + if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) + return STATUS_SUCCESS; + + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) + return STATUS_SUCCESS; + + if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) + return status; + } + + /* last chance exception */ + + status = send_debug_event( rec, FALSE, context ); + if (status != DBG_CONTINUE) + { + if (rec->ExceptionFlags & EH_STACK_INVALID) + ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); + else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) + ERR("Process attempted to continue execution after noncontinuable exception.\n"); + else + ERR("Unhandled exception code %x flags %x addr %p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + NtTerminateProcess( NtCurrentProcess(), 1 ); + } + return STATUS_SUCCESS; +} + + /********************************************************************** * do_segv * @@ -1002,6 +1085,24 @@ void __wine_enter_vm86( CONTEXT *context ) } /*********************************************************************** + * RtlUnwind (NTDLL.@) + */ +void WINAPI RtlUnwind( PVOID pEndFrame, PVOID targetIp, PEXCEPTION_RECORD pRecord, PVOID retval ) +{ + FIXME( "Not implemented on PowerPC\n" ); +} + +/******************************************************************* + * NtRaiseException (NTDLL.@) + */ +NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status = raise_exception( rec, context, first_chance ); + if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); + return status; +} + +/*********************************************************************** * RtlRaiseException (NTDLL.@) */ void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec ) diff --git a/dlls/ntdll/signal_sparc.c b/dlls/ntdll/signal_sparc.c index 87da976dbec..bd7b49b1002 100644 --- a/dlls/ntdll/signal_sparc.c +++ b/dlls/ntdll/signal_sparc.c @@ -152,6 +152,88 @@ static void restore_fpu( CONTEXT *context, ucontext_t *ucontext ) } +/********************************************************************** + * call_stack_handlers + * + * Call the stack handlers chain. + */ +static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + EXCEPTION_POINTERS ptrs; + + FIXME( "not implemented on Sparc\n" ); + + /* hack: call unhandled exception filter directly */ + ptrs.ExceptionRecord = rec; + ptrs.ContextRecord = context; + unhandled_exception_filter( &ptrs ); + return STATUS_UNHANDLED_EXCEPTION; +} + + +/******************************************************************* + * raise_exception + * + * Implementation of NtRaiseException. + */ +static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status; + + if (first_chance) + { + DWORD c; + + TRACE( "code=%x flags=%x addr=%p ip=%x tid=%04x\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, + context->pc, GetCurrentThreadId() ); + for (c = 0; c < rec->NumberParameters; c++) + TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] ); + if (rec->ExceptionCode == EXCEPTION_WINE_STUB) + { + if (rec->ExceptionInformation[1] >> 16) + MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); + else + MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); + } + else + { + /* FIXME: dump context */ + } + + status = send_debug_event( rec, TRUE, context ); + if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) + return STATUS_SUCCESS; + + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) + return STATUS_SUCCESS; + + if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) + return status; + } + + /* last chance exception */ + + status = send_debug_event( rec, FALSE, context ); + if (status != DBG_CONTINUE) + { + if (rec->ExceptionFlags & EH_STACK_INVALID) + ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); + else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) + ERR("Process attempted to continue execution after noncontinuable exception.\n"); + else + ERR("Unhandled exception code %x flags %x addr %p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + NtTerminateProcess( NtCurrentProcess(), 1 ); + } + return STATUS_SUCCESS; +} + + /*********************************************************************** * RtlCaptureContext (NTDLL.@) */ @@ -716,6 +798,24 @@ void __wine_enter_vm86( CONTEXT *context ) } /*********************************************************************** + * RtlUnwind (NTDLL.@) + */ +void WINAPI RtlUnwind( PVOID pEndFrame, PVOID targetIp, PEXCEPTION_RECORD pRecord, PVOID retval ) +{ + FIXME( "Not implemented on Sparc\n" ); +} + +/******************************************************************* + * NtRaiseException (NTDLL.@) + */ +NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status = raise_exception( rec, context, first_chance ); + if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); + return status; +} + +/*********************************************************************** * RtlRaiseException (NTDLL.@) */ void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec ) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 9679c2c7d60..e0b39d5fc39 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -470,6 +470,94 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) /********************************************************************** + * call_stack_handlers + * + * Call the stack handlers chain. + */ +static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) +{ + EXCEPTION_POINTERS ptrs; + + FIXME( "not implemented on x86_64\n" ); + + /* hack: call unhandled exception filter directly */ + ptrs.ExceptionRecord = rec; + ptrs.ContextRecord = context; + unhandled_exception_filter( &ptrs ); + return STATUS_UNHANDLED_EXCEPTION; +} + + +/******************************************************************* + * raise_exception + * + * Implementation of NtRaiseException. + */ +static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status; + + if (first_chance) + { + DWORD c; + + TRACE( "code=%x flags=%x addr=%p ip=%lx tid=%04x\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress, + context->Rip, GetCurrentThreadId() ); + for (c = 0; c < rec->NumberParameters; c++) + TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] ); + if (rec->ExceptionCode == EXCEPTION_WINE_STUB) + { + if (rec->ExceptionInformation[1] >> 16) + MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] ); + else + MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n", + rec->ExceptionAddress, + (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] ); + } + else + { + TRACE(" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", + context->Rax, context->Rbx, context->Rcx, context->Rdx ); + TRACE(" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", + context->Rsi, context->Rdi, context->Rbp, context->Rsp ); + TRACE(" r8=%016lx r9=%016lx r10=%016lx r11=%016lx\n", + context->R8, context->R9, context->R10, context->R11 ); + TRACE(" r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", + context->R12, context->R13, context->R14, context->R15 ); + } + status = send_debug_event( rec, TRUE, context ); + if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) + return STATUS_SUCCESS; + + if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) + return STATUS_SUCCESS; + + if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION) + return status; + } + + /* last chance exception */ + + status = send_debug_event( rec, FALSE, context ); + if (status != DBG_CONTINUE) + { + if (rec->ExceptionFlags & EH_STACK_INVALID) + ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); + else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION) + ERR("Process attempted to continue execution after noncontinuable exception.\n"); + else + ERR("Unhandled exception code %x flags %x addr %p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + NtTerminateProcess( NtCurrentProcess(), rec->ExceptionCode ); + } + return STATUS_SUCCESS; +} + + +/********************************************************************** * segv_handler * * Handler for SIGSEGV and related errors. @@ -804,6 +892,45 @@ PVOID WINAPI RtlVirtualUnwind ( ULONG type, ULONG64 base, ULONG64 pc, } +/******************************************************************* + * RtlUnwind (NTDLL.@) + */ +void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID targetIp, + PEXCEPTION_RECORD pRecord, PVOID retval, CONTEXT *context ) +{ + EXCEPTION_RECORD record; + + /* build an exception record, if we do not have one */ + if (!pRecord) + { + record.ExceptionCode = STATUS_UNWIND; + record.ExceptionFlags = 0; + record.ExceptionRecord = NULL; + record.ExceptionAddress = (void *)context->Rip; + record.NumberParameters = 0; + pRecord = &record; + } + + pRecord->ExceptionFlags |= EH_UNWINDING | (pEndFrame ? 0 : EH_EXIT_UNWIND); + + FIXME( "code=%x flags=%x not implemented on x86_64\n", + pRecord->ExceptionCode, pRecord->ExceptionFlags ); + NtTerminateProcess( GetCurrentProcess(), 1 ); +} +DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) + + +/******************************************************************* + * NtRaiseException (NTDLL.@) + */ +NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) +{ + NTSTATUS status = raise_exception( rec, context, first_chance ); + if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); + return status; +} + + /*********************************************************************** * RtlRaiseException (NTDLL.@) */ diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index 4d7a7db7058..1e72ec21217 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -1197,7 +1197,7 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, hr = get_stgmed_for_stream(h, med); else { - FIXME("Unhandled tymed - emum tymed %x req tymed %x\n", entry->fmtetc.tymed, fmt->tymed); + FIXME("Unhandled tymed - mask %x req tymed %x\n", mask, fmt->tymed); hr = E_FAIL; goto end; } @@ -1214,8 +1214,108 @@ end: static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med) { - FIXME("(%p, %p {%s}, %p): stub\n", iface, fmt, dump_fmtetc(fmt), med); - return E_NOTIMPL; + snapshot *This = impl_from_IDataObject(iface); + HANDLE h; + HRESULT hr; + ole_priv_data *enum_data = NULL; + ole_priv_data_entry *entry; + TYMED supported; + + TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed); + + if ( !fmt || !med ) return E_INVALIDARG; + + if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN; + + if(!This->data) + hr = get_current_dataobject(&This->data); + + if(This->data) + { + hr = IDataObject_GetDataHere(This->data, fmt, med); + if(SUCCEEDED(hr)) + { + CloseClipboard(); + return hr; + } + } + + h = GetClipboardData(fmt->cfFormat); + if(!h) + { + hr = DV_E_FORMATETC; + goto end; + } + + hr = get_priv_data(&enum_data); + if(FAILED(hr)) goto end; + + entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat); + if(entry) + { + if(!td_equal(fmt->ptd, entry->fmtetc.ptd)) + { + hr = DV_E_FORMATETC; + goto end; + } + supported = entry->fmtetc.tymed; + } + else /* non-Ole format */ + supported = TYMED_HGLOBAL; + + switch(med->tymed) + { + case TYMED_HGLOBAL: + { + DWORD src_size = GlobalSize(h); + DWORD dst_size = GlobalSize(med->u.hGlobal); + hr = E_FAIL; + if(dst_size >= src_size) + { + void *src = GlobalLock(h); + void *dst = GlobalLock(med->u.hGlobal); + + memcpy(dst, src, src_size); + GlobalUnlock(med->u.hGlobal); + GlobalUnlock(h); + hr = S_OK; + } + break; + } + case TYMED_ISTREAM: + { + DWORD src_size = GlobalSize(h); + void *src = GlobalLock(h); + hr = IStream_Write(med->u.pstm, src, src_size, NULL); + GlobalUnlock(h); + break; + } + case TYMED_ISTORAGE: + { + STGMEDIUM copy; + if(!(supported & TYMED_ISTORAGE)) + { + hr = E_FAIL; + goto end; + } + hr = get_stgmed_for_storage(h, ©); + if(SUCCEEDED(hr)) + { + hr = IStorage_CopyTo(copy.u.pstg, 0, NULL, NULL, med->u.pstg); + ReleaseStgMedium(©); + } + break; + } + default: + FIXME("Unhandled tymed - supported %x req tymed %x\n", supported, med->tymed); + hr = E_FAIL; + goto end; + } + +end: + HeapFree(GetProcessHeap(), 0, enum_data); + if ( !CloseClipboard() ) hr = CLIPBRD_E_CANT_CLOSE; + return hr; } /************************************************************************ diff --git a/dlls/ole32/memlockbytes.c b/dlls/ole32/memlockbytes.c index 16763cba0ee..57acf37f3cf 100644 --- a/dlls/ole32/memlockbytes.c +++ b/dlls/ole32/memlockbytes.c @@ -160,7 +160,7 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal) return S_OK; } /* It is not our lockbytes implementation, so use a more generic way */ - hres = ILockBytes_Stat(plkbyt,&stbuf,0); + hres = ILockBytes_Stat(plkbyt,&stbuf,STATFLAG_NONAME); if (hres != S_OK) { ERR("Cannot ILockBytes_Stat, %x\n",hres); return hres; diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 132506376dc..9a344653248 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -1904,7 +1904,7 @@ static DWORD WINAPI local_server_thread(LPVOID param) TRACE("marshalling IClassFactory to client\n"); - hres = IStream_Stat(pStm,&ststg,0); + hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME); if (hres) return hres; seekto.u.LowPart = 0; diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 90328f056a5..748eac8048a 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -6310,7 +6310,7 @@ HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){ /* * read a STATSTG structure (contains the clsid) from the storage */ - hRes=IStorage_Stat(pstg,&pstatstg,STATFLAG_DEFAULT); + hRes=IStorage_Stat(pstg,&pstatstg,STATFLAG_NONAME); if(SUCCEEDED(hRes)) *pclsid=pstatstg.clsid; diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index 2b5c711d193..f06a4823ac0 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -1361,10 +1361,160 @@ static void test_nonole_clipboard(void) OleUninitialize(); } +static void test_getdatahere(void) +{ + HRESULT hr; + IDataObject *src, *get; + FORMATETC fmt; + STGMEDIUM med; + + OleInitialize(NULL); + + hr = DataObjectImpl_CreateComplex(&src); + ok(hr == S_OK, "got %08x\n", hr); + + hr = OleSetClipboard(src); + ok(hr == S_OK, "got %08x\n", hr); + + hr = OleGetClipboard(&get); + ok(hr == S_OK, "got %08x\n", hr); + + /* global format -> global & stream */ + + DataObjectImpl_GetData_calls = 0; + DataObjectImpl_GetDataHere_calls = 0; + + InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_HGLOBAL; + U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 1, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls); + + InitFormatEtc(fmt, CF_TEXT, 0); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_HGLOBAL; + U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 2, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_HGLOBAL; + U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 1); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == E_FAIL, "got %08x\n", hr); + ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 3, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTREAM; + CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 4, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTORAGE; + StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == E_FAIL, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 5, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 1, "called %d\n", DataObjectImpl_GetData_calls); + + InitFormatEtc(fmt, cf_stream, 0); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_HGLOBAL; + U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 7, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTREAM; + CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 8, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTORAGE; + StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == E_FAIL, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 9, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 2, "called %d\n", DataObjectImpl_GetData_calls); + + InitFormatEtc(fmt, cf_storage, 0); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_HGLOBAL; + U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 3000); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 11, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTREAM; + CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 12, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls); + + med.pUnkForRelease = NULL; + med.tymed = TYMED_ISTORAGE; + StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &U(med).pstg); + hr = IDataObject_GetDataHere(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); + ReleaseStgMedium(&med); + ok(DataObjectImpl_GetDataHere_calls == 13, "called %d\n", DataObjectImpl_GetDataHere_calls); + ok(DataObjectImpl_GetData_calls == 3, "called %d\n", DataObjectImpl_GetData_calls); + + + IDataObject_Release(get); + IDataObject_Release(src); + + OleUninitialize(); + +} + START_TEST(clipboard) { test_set_clipboard(); test_consumer_refs(); test_flushed_getdata(); test_nonole_clipboard(); + test_getdatahere(); } diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c index 5e863b47579..9d2417452bf 100644 --- a/dlls/oleaut32/tmarshal.c +++ b/dlls/oleaut32/tmarshal.c @@ -213,7 +213,7 @@ _marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) { goto fail; } - hres = IStream_Stat(pStm,&ststg,0); + hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME); if (hres) { ERR("Stream stat failed\n"); goto fail; diff --git a/dlls/rasapi32/tests/rasapi.c b/dlls/rasapi32/tests/rasapi.c index bf1c853b11f..11fca0eb4ad 100644 --- a/dlls/rasapi32/tests/rasapi.c +++ b/dlls/rasapi32/tests/rasapi.c @@ -163,4 +163,6 @@ START_TEST(rasapi) InitFunctionPtrs(); test_rasenum(); + + FreeLibrary(hmodule); } diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 1b9e2446ea0..bbad7481bfc 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -3383,6 +3383,61 @@ static void test_EM_STREAMOUT(void) DestroyWindow(hwndRichEdit); } +static void test_EM_STREAMOUT_FONTTBL(void) +{ + HWND hwndRichEdit = new_richedit(NULL); + EDITSTREAM es; + char buf[1024] = {0}; + char * p; + char * fontTbl; + int brackCount; + + const char * TestItem = "TestSomeText"; + + /* fills in the richedit control with some text */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) TestItem); + + /* streams out the text in rtf format */ + p = buf; + es.dwCookie = (DWORD_PTR)&p; + es.dwError = 0; + es.pfnCallback = test_WM_SETTEXT_esCallback; + memset(buf, 0, sizeof(buf)); + SendMessage(hwndRichEdit, EM_STREAMOUT, + (WPARAM)(SF_RTF), (LPARAM)&es); + + /* scans for \fonttbl, error if not found */ + fontTbl = strstr(buf, "\\fonttbl"); + ok(fontTbl != NULL, "missing \\fonttbl section\n"); + if(fontTbl) + { + /* scans for terminating closing bracket */ + brackCount = 1; + while(*fontTbl && brackCount) + { + if(*fontTbl == '{') + brackCount++; + else if(*fontTbl == '}') + brackCount--; + fontTbl++; + } + /* checks wether closing bracket is ok */ + ok(brackCount == 0, "missing closing bracket in \\fonttbl block\n"); + if(!brackCount) + { + /* char before closing fonttbl block should be a closed bracket */ + fontTbl -= 2; + ok(*fontTbl == '}', "spurious character '%02x' before \\fonttbl closing bracket\n", *fontTbl); + + /* char after fonttbl block should be a crlf */ + fontTbl += 2; + ok(*fontTbl == 0x0d && *(fontTbl+1) == 0x0a, "missing crlf after \\fonttbl block\n"); + } + } + DestroyWindow(hwndRichEdit); +} + + static void test_EM_SETTEXTEX(void) { HWND hwndRichEdit, parent; @@ -6631,6 +6686,7 @@ START_TEST( editor ) test_WM_PASTE(); test_EM_STREAMIN(); test_EM_STREAMOUT(); + test_EM_STREAMOUT_FONTTBL(); test_EM_StreamIn_Undo(); test_EM_FORMATRANGE(); test_unicode_conversions(); diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index b6c3ed6e8e2..6cadbd44425 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -295,10 +295,10 @@ ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, } if (!ME_StreamOutRTFText(pStream, table[i].szFaceName, -1)) return FALSE; - if (!ME_StreamOutPrint(pStream, ";}\r\n")) + if (!ME_StreamOutPrint(pStream, ";}")) return FALSE; } - if (!ME_StreamOutPrint(pStream, "}")) + if (!ME_StreamOutPrint(pStream, "}\r\n")) return FALSE; /* Output colors table if not empty */ diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index f3534d155a5..3e6114400e8 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -1320,6 +1320,17 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI return hr; } +/************************************************************************* + * SHParseDisplayName [SHELL32.@] + */ +HRESULT WINAPI SHParseDisplayName(LPCWSTR name, IBindCtx *bindctx, LPITEMIDLIST *pidlist, + SFGAOF attr_in, SFGAOF *attr_out) +{ + FIXME("%s %p %p %d %p stub!\n", debugstr_w(name), bindctx, pidlist, attr_in, attr_out); + if(pidlist) *pidlist = NULL; + return E_NOTIMPL; +} + /************************************************************************** * * internal functions diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 5713c498fa7..b3fc7623487 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -373,6 +373,7 @@ @ stdcall SHIsFileAvailableOffline(wstr ptr) @ stdcall SHLoadInProc(long) @ stdcall SHLoadNonloadedIconOverlayIdentifiers() +@ stdcall SHParseDisplayName(wstr ptr ptr long ptr) @ stdcall SHPathPrepareForWriteA(long ptr str long) @ stdcall SHPathPrepareForWriteW(long ptr wstr long) @ stdcall SHQueryRecycleBinA(str ptr) diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index ea19c778eaa..e136d4bf103 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -671,7 +671,9 @@ static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HR if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST) ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError); else - ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n"); + ok(dwError != ERROR_SUCCESS || + broken(tested_protocol == MK_TEST), /* Win9x, WinME and NT4 */ + "dwError == ERROR_SUCCESS\n"); ok(!szResult, "szResult != NULL\n"); return S_OK; diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index f7231f902bd..eaa805bf64b 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -1684,12 +1684,19 @@ static LRESULT LISTBOX_InsertString( LB_DESCR *descr, INT index, LPCWSTR str ) */ static void LISTBOX_DeleteItem( LB_DESCR *descr, INT index ) { + /* save the item data before it gets freed by LB_RESETCONTENT */ + ULONG_PTR item_data = descr->items[index].data; + LPWSTR item_str = descr->items[index].str; + + if (!descr->nb_items) + SendMessageW( descr->self, LB_RESETCONTENT, 0, 0 ); + /* Note: Win 3.1 only sends DELETEITEM on owner-draw items, * while Win95 sends it for all items with user data. * It's probably better to send it too often than not * often enough, so this is what we do here. */ - if (IS_OWNERDRAW(descr) || descr->items[index].data) + if (IS_OWNERDRAW(descr) || item_data) { DELETEITEMSTRUCT dis; UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID ); @@ -1698,11 +1705,11 @@ static void LISTBOX_DeleteItem( LB_DESCR *descr, INT index ) dis.CtlID = id; dis.itemID = index; dis.hwndItem = descr->self; - dis.itemData = descr->items[index].data; + dis.itemData = item_data; SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis ); } if (HAS_STRINGS(descr)) - HeapFree( GetProcessHeap(), 0, descr->items[index].str ); + HeapFree( GetProcessHeap(), 0, item_str ); } @@ -1718,18 +1725,20 @@ static LRESULT LISTBOX_RemoveItem( LB_DESCR *descr, INT index ) if ((index < 0) || (index >= descr->nb_items)) return LB_ERR; + descr->nb_items--; + LISTBOX_DeleteItem( descr, index ); + + if (!descr->nb_items) return LB_OKAY; + /* We need to invalidate the original rect instead of the updated one. */ LISTBOX_InvalidateItems( descr, index ); - LISTBOX_DeleteItem( descr, index ); - /* Remove the item */ item = &descr->items[index]; - if (index < descr->nb_items-1) + if (index < descr->nb_items) RtlMoveMemory( item, item + 1, - (descr->nb_items - index - 1) * sizeof(LB_ITEMDATA) ); - descr->nb_items--; + (descr->nb_items - index) * sizeof(LB_ITEMDATA) ); if (descr->anchor_item == descr->nb_items) descr->anchor_item--; /* Shrink the item array if possible */ diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index f698b7f3eae..2445f82b5c7 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -11017,6 +11017,19 @@ static const struct message wm_lb_click_0[] = { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) }, { 0 } }; +static const struct message wm_lb_deletestring[] = +{ + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 }, + { 0 } +}; +static const struct message wm_lb_deletestring_reset[] = +{ + { LB_DELETESTRING, sent|wparam|lparam, 0, 0 }, + { LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 }, + { WM_DELETEITEM, sent|wparam|parent, ID_LISTBOX, 0 }, + { 0 } +}; #define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__) @@ -11127,6 +11140,33 @@ static void test_listbox_messages(void) check_lb_state(listbox, 3, 0, 0, 0); flush_sequence(); + trace("deleting item 0\n"); + ret = SendMessage(listbox, LB_DELETESTRING, 0, 0); + ok(ret == 2, "expected 2, got %ld\n", ret); + ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE ); + check_lb_state(listbox, 2, -1, 0, 0); + flush_sequence(); + + trace("deleting item 0\n"); + ret = SendMessage(listbox, LB_DELETESTRING, 0, 0); + ok(ret == 1, "expected 1, got %ld\n", ret); + ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE ); + check_lb_state(listbox, 1, -1, 0, 0); + flush_sequence(); + + trace("deleting item 0\n"); + ret = SendMessage(listbox, LB_DELETESTRING, 0, 0); + ok(ret == 0, "expected 0, got %ld\n", ret); + ok_sequence(wm_lb_deletestring_reset, "LB_DELETESTRING 0", FALSE ); + check_lb_state(listbox, 0, -1, 0, 0); + flush_sequence(); + + trace("deleting item 0\n"); + ret = SendMessage(listbox, LB_DELETESTRING, 0, 0); + ok(ret == LB_ERR, "expected LB_ERR, got %ld\n", ret); + check_lb_state(listbox, 0, -1, 0, 0); + flush_sequence(); + log_all_parent_messages--; DestroyWindow(listbox); diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 46080cac8a5..0c36ff82bd3 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -206,6 +206,128 @@ static void scrollbar_test4(void) sbi.rcScrollBar.bottom, sbi.rcScrollBar.right ); } +/* some tests designed to show that Horizontal and Vertical + * window scroll bar info are not created independently */ +static void scrollbar_test_default( DWORD style) +{ + INT min, max, ret; + HWND hwnd; + SCROLLINFO si = { sizeof( SCROLLINFO), SIF_TRACKPOS }; + + hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style, + 0, 0, 10, 10, 0, 0, 0, NULL); + assert( hwnd != 0); + + ret = GetScrollRange( hwnd, SB_VERT, &min, &max); + ok( ret || + broken( !ret) /* Win 98/ME */ , "GetScrollRange failed.\n"); + /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */ + if( !( style & ( WS_VSCROLL | WS_HSCROLL))) + ok( min == 0 && max == 0, + "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); + else + ok( min == 0 && max == 100, + "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); + ret = GetScrollRange( hwnd, SB_HORZ, &min, &max); + ok( ret || + broken( !ret) /* Win 98/ME */ , "GetScrollRange failed.\n"); + /* range is 0,0 if there are no H or V scroll bars. 0,100 otherwise */ + if( !( style & ( WS_VSCROLL | WS_HSCROLL))) + ok( min == 0 && max == 0, + "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style); + else + ok( min == 0 && max == 100, + "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); + /* test GetScrollInfo, vist for vertical SB */ + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should fail if no H orV scroll bar styles are present. Succeed otherwise */ + if( !( style & ( WS_VSCROLL | WS_HSCROLL))) + ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); + else + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* Same for Horizontal SB */ + ret = GetScrollInfo( hwnd, SB_HORZ, &si); + /* should fail if no H orV scroll bar styles are present. Succeed otherwise */ + if( !( style & ( WS_VSCROLL | WS_HSCROLL))) + ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style); + else + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* now set the Vertical Scroll range to something that could be the default value it + * already has */; + ret = SetScrollRange( hwnd, SB_VERT, 0, 100, FALSE); + ok( ret, "SetScrollRange failed.\n"); + /* and request the Horizontal range */ + ret = GetScrollRange( hwnd, SB_HORZ, &min, &max); + ok( ret, "GetScrollRange failed.\n"); + /* now the range should be 0,100 in ALL cases */ +todo_wine + ok( min == 0 && max == 100, + "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); + /* See what is different now for GetScrollRange */ + ret = GetScrollInfo( hwnd, SB_HORZ, &si); + /* should succeed in ALL cases */ +todo_wine + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should succeed in ALL cases */ + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* do the test again with H and V reversed. + * Start with a clean window */ + DestroyWindow( hwnd); + hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style, + 0, 0, 10, 10, 0, 0, 0, NULL); + assert( hwnd != 0); + /* Set Horizonta Scroll range to something that could be the default value it + * already has */; + ret = SetScrollRange( hwnd, SB_HORZ, 0, 100, FALSE); + ok( ret, "SetScrollRange failed.\n"); + /* and request the Vertical range */ + ret = GetScrollRange( hwnd, SB_VERT, &min, &max); + ok( ret, "GetScrollRange failed.\n"); + /* now the range should be 0,100 in ALL cases */ +todo_wine + ok( min == 0 && max == 100, + "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); + /* See what is different now for GetScrollRange */ + ret = GetScrollInfo( hwnd, SB_HORZ, &si); + /* should succeed in ALL cases */ + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should succeed in ALL cases */ +todo_wine + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* Slightly change the test to muse SetScrollInfo + * Start with a clean window */ + DestroyWindow( hwnd); + hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style, + 0, 0, 10, 10, 0, 0, 0, NULL); + assert( hwnd != 0); + /* set Horizontal position with SetScrollInfo */ + si.nPos = 0; + si.nMin = 11; + si.nMax = 22; + si.fMask |= SIF_RANGE; + ret = SetScrollInfo( hwnd, SB_HORZ, &si, FALSE); + ok( ret, "SetScrollInfo failed. Style is %08x\n", style); + /* and request the Vertical range */ + ret = GetScrollRange( hwnd, SB_VERT, &min, &max); + ok( ret, "GetScrollRange failed.\n"); + /* now the range should be 0,100 in ALL cases */ +todo_wine + ok( min == 0 && max == 100, + "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style); + /* See what is different now for GetScrollRange */ + ret = GetScrollInfo( hwnd, SB_HORZ, &si); + /* should succeed in ALL cases */ + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + ret = GetScrollInfo( hwnd, SB_VERT, &si); + /* should succeed in ALL cases */ +todo_wine + ok( ret, "GetScrollInfo failed unexpectedly. Style is %08x\n", style); + /* clean up */ + DestroyWindow( hwnd); +} + START_TEST ( scroll ) { WNDCLASSA wc; @@ -236,6 +358,12 @@ START_TEST ( scroll ) scrollbar_test3(); scrollbar_test4(); + scrollbar_test_default( 0); +if( 0) { /* enable this when the todo's in scrollbar_test_default are fixed */ + scrollbar_test_default( WS_HSCROLL); + scrollbar_test_default( WS_VSCROLL); + scrollbar_test_default( WS_HSCROLL | WS_VSCROLL); +} DestroyWindow(hScroll); DestroyWindow(hMainWnd); } diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index fc3417cc3a1..ddc6da7634d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -659,7 +659,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD const char *dst_str, const char *coord_reg, BOOL projected, BOOL bias) { SHADER_BUFFER *buffer = ins->ctx->buffer; - DWORD sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; const char *tex_type; IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 6bc7aacd051..acc4b71ad36 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -38,6 +38,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); #define WINED3DSP_DCL_USAGEINDEX_SHIFT 16 #define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT) +/* DCL sampler type */ +#define WINED3DSP_TEXTURETYPE_SHIFT 27 +#define WINED3DSP_TEXTURETYPE_MASK (0xf << WINED3DSP_TEXTURETYPE_SHIFT) + /* Opcode-related masks */ #define WINED3DSI_OPCODE_MASK 0x0000ffff @@ -90,7 +94,8 @@ typedef enum _WINED3DSHADER_ADDRESSMODE_TYPE WINED3DSHADER_ADDRMODE_FORCE_DWORD = 0x7fffffff, } WINED3DSHADER_ADDRESSMODE_TYPE; -static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version); +static void shader_dump_src_param(const struct wined3d_shader_src_param *param, DWORD shader_version); +static void shader_dump_dst_param(const struct wined3d_shader_dst_param *param, DWORD shader_version); /* Read a parameter opcode from the input stream, * and possibly a relative addressing token. @@ -128,8 +133,7 @@ static const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, { DWORD i = 0; - /** TODO: use dichotomic search */ - while (opcode_table[i].name) + while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE) { if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode && shader_version >= opcode_table[i].min_version @@ -155,6 +159,29 @@ static inline int shader_skip_opcode(const SHADER_OPCODE *opcode_info, DWORD opc ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->num_params; } +static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, + struct wined3d_shader_src_param *src) +{ + src->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) + | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); + src->register_idx = param & WINED3DSP_REGNUM_MASK; + src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; + src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT; + src->rel_addr = rel_addr; +} + +static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, + struct wined3d_shader_dst_param *dst) +{ + dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) + | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); + dst->register_idx = param & WINED3DSP_REGNUM_MASK; + dst->write_mask = param & WINED3DSP_WRITEMASK_ALL; + dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT; + dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + dst->rel_addr = rel_addr; +} + /* Read the parameters of an unrecognized opcode from the input stream * Return the number of tokens read. * @@ -170,11 +197,29 @@ static int shader_skip_unrecognized(const DWORD *ptr, DWORD shader_version) while (*ptr & 0x80000000) { DWORD token, addr_token = 0; + struct wined3d_shader_src_param rel_addr; + tokens_read += shader_get_param(ptr, shader_version, &token, &addr_token); ptr += tokens_read; FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token); - shader_dump_param(token, addr_token, i, shader_version); + + if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr); + + if (!i) + { + struct wined3d_shader_dst_param dst; + + shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst); + shader_dump_dst_param(&dst, shader_version); + } + else + { + struct wined3d_shader_src_param src; + + shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src); + shader_dump_src_param(&src, shader_version); + } FIXME("\n"); ++i; } @@ -206,6 +251,138 @@ static void shader_sm1_read_opcode(const DWORD **ptr, struct wined3d_shader_inst *param_size = shader_skip_opcode(opcode_info, opcode_token, shader_version); } +static void shader_sm1_read_src_param(const DWORD **ptr, struct wined3d_shader_src_param *src_param, + struct wined3d_shader_src_param *src_rel_addr, DWORD shader_version) +{ + DWORD token, addr_token; + + *ptr += shader_get_param(*ptr, shader_version, &token, &addr_token); + if (token & WINED3DSHADER_ADDRMODE_RELATIVE) + { + shader_parse_src_param(addr_token, NULL, src_rel_addr); + shader_parse_src_param(token, src_rel_addr, src_param); + } + else + { + shader_parse_src_param(token, NULL, src_param); + } +} + +static void shader_sm1_read_dst_param(const DWORD **ptr, struct wined3d_shader_dst_param *dst_param, + struct wined3d_shader_src_param *dst_rel_addr, DWORD shader_version) +{ + DWORD token, addr_token; + + *ptr += shader_get_param(*ptr, shader_version, &token, &addr_token); + if (token & WINED3DSHADER_ADDRMODE_RELATIVE) + { + shader_parse_src_param(addr_token, NULL, dst_rel_addr); + shader_parse_dst_param(token, dst_rel_addr, dst_param); + } + else + { + shader_parse_dst_param(token, NULL, dst_param); + } +} + +static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic) +{ + DWORD usage_token = *(*ptr)++; + DWORD dst_token = *(*ptr)++; + + semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; + semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT; + shader_parse_dst_param(dst_token, NULL, &semantic->reg); +} + +static const char *shader_opcode_names[] = +{ + /* WINED3DSIH_ABS */ "abs", + /* WINED3DSIH_ADD */ "add", + /* WINED3DSIH_BEM */ "bem", + /* WINED3DSIH_BREAK */ "break", + /* WINED3DSIH_BREAKC */ "breakc", + /* WINED3DSIH_BREAKP */ "breakp", + /* WINED3DSIH_CALL */ "call", + /* WINED3DSIH_CALLNZ */ "callnz", + /* WINED3DSIH_CMP */ "cmp", + /* WINED3DSIH_CND */ "cnd", + /* WINED3DSIH_CRS */ "crs", + /* WINED3DSIH_DCL */ "dcl", + /* WINED3DSIH_DEF */ "def", + /* WINED3DSIH_DEFB */ "defb", + /* WINED3DSIH_DEFI */ "defi", + /* WINED3DSIH_DP2ADD */ "dp2add", + /* WINED3DSIH_DP3 */ "dp3", + /* WINED3DSIH_DP4 */ "dp4", + /* WINED3DSIH_DST */ "dst", + /* WINED3DSIH_DSX */ "dsx", + /* WINED3DSIH_DSY */ "dsy", + /* WINED3DSIH_ELSE */ "else", + /* WINED3DSIH_ENDIF */ "endif", + /* WINED3DSIH_ENDLOOP */ "endloop", + /* WINED3DSIH_ENDREP */ "endrep", + /* WINED3DSIH_EXP */ "exp", + /* WINED3DSIH_EXPP */ "expp", + /* WINED3DSIH_FRC */ "frc", + /* WINED3DSIH_IF */ "if", + /* WINED3DSIH_IFC */ "ifc", + /* WINED3DSIH_LABEL */ "label", + /* WINED3DSIH_LIT */ "lit", + /* WINED3DSIH_LOG */ "log", + /* WINED3DSIH_LOGP */ "logp", + /* WINED3DSIH_LOOP */ "loop", + /* WINED3DSIH_LRP */ "lrp", + /* WINED3DSIH_M3x2 */ "m3x2", + /* WINED3DSIH_M3x3 */ "m3x3", + /* WINED3DSIH_M3x4 */ "m3x4", + /* WINED3DSIH_M4x3 */ "m4x3", + /* WINED3DSIH_M4x4 */ "m4x4", + /* WINED3DSIH_MAD */ "mad", + /* WINED3DSIH_MAX */ "max", + /* WINED3DSIH_MIN */ "min", + /* WINED3DSIH_MOV */ "mov", + /* WINED3DSIH_MOVA */ "mova", + /* WINED3DSIH_MUL */ "mul", + /* WINED3DSIH_NOP */ "nop", + /* WINED3DSIH_NRM */ "nrm", + /* WINED3DSIH_PHASE */ "phase", + /* WINED3DSIH_POW */ "pow", + /* WINED3DSIH_RCP */ "rcp", + /* WINED3DSIH_REP */ "rep", + /* WINED3DSIH_RET */ "ret", + /* WINED3DSIH_RSQ */ "rsq", + /* WINED3DSIH_SETP */ "setp", + /* WINED3DSIH_SGE */ "sge", + /* WINED3DSIH_SGN */ "sgn", + /* WINED3DSIH_SINCOS */ "sincos", + /* WINED3DSIH_SLT */ "slt", + /* WINED3DSIH_SUB */ "sub", + /* WINED3DSIH_TEX */ "texld", + /* WINED3DSIH_TEXBEM */ "texbem", + /* WINED3DSIH_TEXBEML */ "texbeml", + /* WINED3DSIH_TEXCOORD */ "texcrd", + /* WINED3DSIH_TEXDEPTH */ "texdepth", + /* WINED3DSIH_TEXDP3 */ "texdp3", + /* WINED3DSIH_TEXDP3TEX */ "texdp3tex", + /* WINED3DSIH_TEXKILL */ "texkill", + /* WINED3DSIH_TEXLDD */ "texldd", + /* WINED3DSIH_TEXLDL */ "texldl", + /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth", + /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad", + /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex", + /* WINED3DSIH_TEXM3x3 */ "texm3x3", + /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff", + /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad", + /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec", + /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex", + /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec", + /* WINED3DSIH_TEXREG2AR */ "texreg2ar", + /* WINED3DSIH_TEXREG2GB */ "texreg2gb", + /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb", +}; + static inline BOOL shader_is_version_token(DWORD token) { return shader_is_pshader_version(token) || shader_is_vshader_version(token); @@ -295,20 +472,18 @@ static inline BOOL shader_is_comment(DWORD token) /* Convert floating point offset relative * to a register file to an absolute offset for float constants */ -static unsigned int shader_get_float_offset(const DWORD reg) +static unsigned int shader_get_float_offset(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx) { - unsigned int regnum = reg & WINED3DSP_REGNUM_MASK; - int regtype = shader_get_regtype(reg); - - switch (regtype) { - case WINED3DSPR_CONST: return regnum; - case WINED3DSPR_CONST2: return 2048 + regnum; - case WINED3DSPR_CONST3: return 4096 + regnum; - case WINED3DSPR_CONST4: return 6144 + regnum; + switch (register_type) + { + case WINED3DSPR_CONST: return register_idx; + case WINED3DSPR_CONST2: return 2048 + register_idx; + case WINED3DSPR_CONST3: return 4096 + register_idx; + case WINED3DSPR_CONST4: return 6144 + register_idx; default: - FIXME("Unsupported register type: %d\n", regtype); - return regnum; - } + FIXME("Unsupported register type: %d\n", register_type); + return register_idx; + } } static void shader_delete_constant_list(struct list* clist) { @@ -325,27 +500,76 @@ static void shader_delete_constant_list(struct list* clist) { list_init(clist); } -static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, - struct wined3d_shader_dst_param *dst) +static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps, + DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader) { - dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) - | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); - dst->register_idx = param & WINED3DSP_REGNUM_MASK; - dst->write_mask = param & WINED3DSP_WRITEMASK_ALL; - dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT; - dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - dst->rel_addr = rel_addr; -} + switch (register_type) + { + case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */ + if (pshader) reg_maps->texcoord[register_idx] = 1; + else reg_maps->address[register_idx] = 1; + break; -static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, - struct wined3d_shader_src_param *src) -{ - src->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) - | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); - src->register_idx = param & WINED3DSP_REGNUM_MASK; - src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; - src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT; - src->rel_addr = rel_addr; + case WINED3DSPR_TEMP: + reg_maps->temporary[register_idx] = 1; + break; + + case WINED3DSPR_INPUT: + if (!pshader) reg_maps->attributes[register_idx] = 1; + else + { + if (has_rel_addr) + { + /* If relative addressing is used, we must assume that all registers + * are used. Even if it is a construct like v3[aL], we can't assume + * that v0, v1 and v2 aren't read because aL can be negative */ + unsigned int i; + for (i = 0; i < MAX_REG_INPUT; ++i) + { + ((IWineD3DPixelShaderImpl *)This)->input_reg_used[i] = TRUE; + } + } + else + { + ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE; + } + } + break; + + case WINED3DSPR_RASTOUT: + if (register_idx == 1) reg_maps->fog = 1; + break; + + case WINED3DSPR_MISCTYPE: + if (pshader && register_idx == 0) reg_maps->vpos = 1; + break; + + case WINED3DSPR_CONST: + if (has_rel_addr) + { + if (!pshader) + { + if (register_idx <= ((IWineD3DVertexShaderImpl *)This)->min_rel_offset) + ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = register_idx; + else if (register_idx >= ((IWineD3DVertexShaderImpl *)This)->max_rel_offset) + ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = register_idx; + } + reg_maps->usesrelconstF = TRUE; + } + break; + + case WINED3DSPR_CONSTINT: + reg_maps->integer_constants |= (1 << register_idx); + break; + + case WINED3DSPR_CONSTBOOL: + reg_maps->boolean_constants |= (1 << register_idx); + break; + + default: + TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx); + break; + } } /* Note that this does not count the loop register @@ -364,8 +588,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m /* There are some minor differences between pixel and vertex shaders */ - memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat)); - memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams)); + memset(reg_maps, 0, sizeof(*reg_maps)); /* get_registers_used is called on every compile on some 1.x shaders, which can result * in stacking up a collection of local constants. Delete the old constants if existing @@ -410,39 +633,36 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m /* Handle declarations */ if (ins.handler_idx == WINED3DSIH_DCL) { - DWORD usage = *pToken++; - DWORD param = *pToken++; - DWORD regtype = shader_get_regtype(param); - unsigned int regnum = param & WINED3DSP_REGNUM_MASK; + struct wined3d_shader_semantic semantic; - /* Vshader: mark attributes used - Pshader: mark 3.0 input registers used, save token */ - if (WINED3DSPR_INPUT == regtype) { + shader_sm1_read_semantic(&pToken, &semantic); - if (!pshader) - reg_maps->attributes[regnum] = 1; - else - reg_maps->packed_input[regnum] = 1; - - semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - semantics_in[regnum].usage_idx = - (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_parse_dst_param(param, NULL, &semantics_in[regnum].reg); - - /* Vshader: mark 3.0 output registers used, save token */ - } else if (WINED3DSPR_OUTPUT == regtype) { - reg_maps->packed_output[regnum] = 1; - semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - semantics_out[regnum].usage_idx = - (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_parse_dst_param(param, NULL, &semantics_out[regnum].reg); - - if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT)) - reg_maps->fog = 1; - - /* Save sampler usage token */ - } else if (WINED3DSPR_SAMPLER == regtype) - reg_maps->samplers[regnum] = usage; + switch (semantic.reg.register_type) + { + /* Vshader: mark attributes used + * Pshader: mark 3.0 input registers used, save token */ + case WINED3DSPR_INPUT: + if (!pshader) reg_maps->attributes[semantic.reg.register_idx] = 1; + else reg_maps->packed_input[semantic.reg.register_idx] = 1; + semantics_in[semantic.reg.register_idx] = semantic; + break; + + /* Vshader: mark 3.0 output registers used, save token */ + case WINED3DSPR_OUTPUT: + reg_maps->packed_output[semantic.reg.register_idx] = 1; + semantics_out[semantic.reg.register_idx] = semantic; + if (semantic.usage == WINED3DDECLUSAGE_FOG) reg_maps->fog = 1; + break; + + /* Save sampler usage token */ + case WINED3DSPR_SAMPLER: + reg_maps->sampler_type[semantic.reg.register_idx] = semantic.sampler_type; + break; + + default: + TRACE("Not recording DCL register type %#x.\n", semantic.reg.register_type); + break; + } } else if (ins.handler_idx == WINED3DSIH_DEF) { @@ -490,13 +710,21 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m else if (ins.handler_idx == WINED3DSIH_LOOP || ins.handler_idx == WINED3DSIH_REP) { + DWORD reg; + + if(ins.handler_idx == WINED3DSIH_LOOP) { + reg = pToken[1]; + } else { + reg = pToken[0]; + } + cur_loop_depth++; if(cur_loop_depth > max_loop_depth) max_loop_depth = cur_loop_depth; pToken += param_size; /* Rep and Loop always use an integer constant for the control parameters */ - This->baseShader.uses_int_consts = TRUE; + reg_maps->integer_constants |= (1 << (reg & WINED3DSP_REGNUM_MASK)); } else if (ins.handler_idx == WINED3DSIH_ENDLOOP || ins.handler_idx == WINED3DSIH_ENDREP) @@ -535,7 +763,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK; TRACE("Setting fake 2D sampler for 1.x pixelshader\n"); - reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; + reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D; /* texbem is only valid with < 1.4 pixel shaders */ if (ins.handler_idx == WINED3DSIH_TEXBEM @@ -563,86 +791,42 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m } /* This will loop over all the registers and try to - * make a bitmask of the ones we're interested in. + * make a bitmask of the ones we're interested in. * - * Relative addressing tokens are ignored, but that's - * okay, since we'll catch any address registers when + * Relative addressing tokens are ignored, but that's + * okay, since we'll catch any address registers when * they are initialized (required by spec) */ - limit = ins.dst_count + ins.src_count + (ins.predicate ? 1 : 0); - - for (i = 0; i < limit; ++i) { - - DWORD param, addr_token, reg, regtype; - pToken += shader_get_param(pToken, shader_version, ¶m, &addr_token); - - regtype = shader_get_regtype(param); - reg = param & WINED3DSP_REGNUM_MASK; + if (ins.dst_count) + { + struct wined3d_shader_dst_param dst_param; + struct wined3d_shader_src_param dst_rel_addr; - if (WINED3DSPR_TEXTURE == regtype) { /* vs: WINED3DSPR_ADDR */ + shader_sm1_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); - if (pshader) - reg_maps->texcoord[reg] = 1; - else - reg_maps->address[reg] = 1; + /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and + * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel + * shaders because TECRDOUT isn't used in them, but future register types might cause issues */ + if (!pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3 + && dst_param.register_type == WINED3DSPR_TEXCRDOUT) + { + reg_maps->texcoord_mask[dst_param.register_type] |= dst_param.write_mask; } - - else if (WINED3DSPR_TEMP == regtype) - reg_maps->temporary[reg] = 1; - - else if (WINED3DSPR_INPUT == regtype) { - if( !pshader) - reg_maps->attributes[reg] = 1; - else { - if(param & WINED3DSHADER_ADDRMODE_RELATIVE) { - /* If relative addressing is used, we must assume that all registers - * are used. Even if it is a construct like v3[aL], we can't assume - * that v0, v1 and v2 aren't read because aL can be negative - */ - unsigned int i; - for(i = 0; i < MAX_REG_INPUT; i++) { - ((IWineD3DPixelShaderImpl *) This)->input_reg_used[i] = TRUE; - } - } else { - ((IWineD3DPixelShaderImpl *) This)->input_reg_used[reg] = TRUE; - } - } + else + { + shader_record_register_usage(This, reg_maps, dst_param.register_type, + dst_param.register_idx, !!dst_param.rel_addr, pshader); } + } - else if (WINED3DSPR_RASTOUT == regtype && reg == 1) - reg_maps->fog = 1; - - else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader) - reg_maps->vpos = 1; - - else if(WINED3DSPR_CONST == regtype) { - if(param & WINED3DSHADER_ADDRMODE_RELATIVE) { - if(!pshader) { - if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) { - ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg; - } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) { - ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg; - } - } - reg_maps->usesrelconstF = TRUE; - } - } - else if(WINED3DSPR_CONSTINT == regtype) { - This->baseShader.uses_int_consts = TRUE; - } - else if(WINED3DSPR_CONSTBOOL == regtype) { - This->baseShader.uses_bool_consts = TRUE; - } + limit = ins.src_count + (ins.predicate ? 1 : 0); + for (i = 0; i < limit; ++i) + { + struct wined3d_shader_src_param src_param, src_rel_addr; - /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used - * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT - * isn't used in them, but future register types might cause issues - */ - else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ - && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3) - { - reg_maps->texcoord_mask[reg] |= shader_get_writemask(param); - } + shader_sm1_read_src_param(&pToken, &src_param, &src_rel_addr, shader_version); + shader_record_register_usage(This, reg_maps, src_param.register_type, + src_param.register_idx, !!src_param.rel_addr, pshader); } } } @@ -654,265 +838,268 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m return WINED3D_OK; } -static void shader_dump_decl_usage(DWORD decl, DWORD param, DWORD shader_version) +static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic, DWORD shader_version) { - DWORD regtype = shader_get_regtype(param); - TRACE("dcl"); - if (regtype == WINED3DSPR_SAMPLER) { - DWORD ttype = decl & WINED3DSP_TEXTURETYPE_MASK; - - switch (ttype) { + if (semantic->reg.register_type == WINED3DSPR_SAMPLER) + { + switch (semantic->sampler_type) + { case WINED3DSTT_2D: TRACE("_2d"); break; case WINED3DSTT_CUBE: TRACE("_cube"); break; case WINED3DSTT_VOLUME: TRACE("_volume"); break; - default: TRACE("_unknown_ttype(0x%08x)", ttype); - } - - } else { - - DWORD usage = decl & WINED3DSP_DCL_USAGE_MASK; - DWORD idx = (decl & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - + default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type); + } + } + else + { /* Pixel shaders 3.0 don't have usage semantics */ if (shader_is_pshader_version(shader_version) && shader_version < WINED3DPS_VERSION(3,0)) return; else TRACE("_"); - switch(usage) { - case WINED3DDECLUSAGE_POSITION: - TRACE("position%d", idx); - break; - case WINED3DDECLUSAGE_BLENDINDICES: - TRACE("blend"); - break; - case WINED3DDECLUSAGE_BLENDWEIGHT: - TRACE("weight"); - break; - case WINED3DDECLUSAGE_NORMAL: - TRACE("normal%d", idx); - break; - case WINED3DDECLUSAGE_PSIZE: - TRACE("psize"); - break; - case WINED3DDECLUSAGE_COLOR: - if(idx == 0) { - TRACE("color"); - } else { - TRACE("specular%d", (idx - 1)); - } - break; - case WINED3DDECLUSAGE_TEXCOORD: - TRACE("texture%d", idx); - break; - case WINED3DDECLUSAGE_TANGENT: - TRACE("tangent"); - break; - case WINED3DDECLUSAGE_BINORMAL: - TRACE("binormal"); - break; - case WINED3DDECLUSAGE_TESSFACTOR: - TRACE("tessfactor"); - break; - case WINED3DDECLUSAGE_POSITIONT: - TRACE("positionT%d", idx); - break; - case WINED3DDECLUSAGE_FOG: - TRACE("fog"); - break; - case WINED3DDECLUSAGE_DEPTH: - TRACE("depth"); - break; - case WINED3DDECLUSAGE_SAMPLE: - TRACE("sample"); - break; - default: - FIXME("unknown_semantics(0x%08x)", usage); + switch (semantic->usage) + { + case WINED3DDECLUSAGE_POSITION: + TRACE("position%d", semantic->usage_idx); + break; + case WINED3DDECLUSAGE_BLENDINDICES: + TRACE("blend"); + break; + case WINED3DDECLUSAGE_BLENDWEIGHT: + TRACE("weight"); + break; + case WINED3DDECLUSAGE_NORMAL: + TRACE("normal%d", semantic->usage_idx); + break; + case WINED3DDECLUSAGE_PSIZE: + TRACE("psize"); + break; + case WINED3DDECLUSAGE_COLOR: + if (semantic->usage_idx == 0) TRACE("color"); + else TRACE("specular%d", (semantic->usage_idx - 1)); + break; + case WINED3DDECLUSAGE_TEXCOORD: + TRACE("texture%d", semantic->usage_idx); + break; + case WINED3DDECLUSAGE_TANGENT: + TRACE("tangent"); + break; + case WINED3DDECLUSAGE_BINORMAL: + TRACE("binormal"); + break; + case WINED3DDECLUSAGE_TESSFACTOR: + TRACE("tessfactor"); + break; + case WINED3DDECLUSAGE_POSITIONT: + TRACE("positionT%d", semantic->usage_idx); + break; + case WINED3DDECLUSAGE_FOG: + TRACE("fog"); + break; + case WINED3DDECLUSAGE_DEPTH: + TRACE("depth"); + break; + case WINED3DDECLUSAGE_SAMPLE: + TRACE("sample"); + break; + default: + FIXME("unknown_semantics(0x%08x)", semantic->usage); } } } -static void shader_dump_arr_entry(const DWORD param, const DWORD addr_token, - unsigned int reg, int input, DWORD shader_version) +static void shader_dump_arr_entry(const struct wined3d_shader_src_param *rel_addr, + UINT register_idx, DWORD shader_version) { - char relative = - ((param & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE); - - if (relative) { + if (rel_addr) + { TRACE("["); - if (addr_token) - shader_dump_param(addr_token, 0, input, shader_version); - else - TRACE("a0.x"); + shader_dump_src_param(rel_addr, shader_version); TRACE(" + "); - } - TRACE("%u", reg); - if (relative) - TRACE("]"); + } + TRACE("%u", register_idx); + if (rel_addr) TRACE("]"); } -static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version) +static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx, + const struct wined3d_shader_src_param *rel_addr, DWORD shader_version) { - static const char * const rastout_reg_names[] = { "oPos", "oFog", "oPts" }; - static const char * const misctype_reg_names[] = { "vPos", "vFace"}; - const char *swizzle_reg_chars = "xyzw"; - - DWORD reg = param & WINED3DSP_REGNUM_MASK; - DWORD regtype = shader_get_regtype(param); - DWORD modifier = param & WINED3DSP_SRCMOD_MASK; + static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"}; + static const char * const misctype_reg_names[] = {"vPos", "vFace"}; - /* There are some minor differences between pixel and vertex shaders */ - char pshader = shader_is_pshader_version(shader_version); - - if (input) { - if ( (modifier == WINED3DSPSM_NEG) || - (modifier == WINED3DSPSM_BIASNEG) || - (modifier == WINED3DSPSM_SIGNNEG) || - (modifier == WINED3DSPSM_X2NEG) || - (modifier == WINED3DSPSM_ABSNEG) ) - TRACE("-"); - else if (modifier == WINED3DSPSM_COMP) - TRACE("1-"); - else if (modifier == WINED3DSPSM_NOT) - TRACE("!"); - - if (modifier == WINED3DSPSM_ABS || modifier == WINED3DSPSM_ABSNEG) - TRACE("abs("); - } - - switch (regtype) { + switch (register_type) + { case WINED3DSPR_TEMP: - TRACE("r%u", reg); + TRACE("r%u", register_idx); break; + case WINED3DSPR_INPUT: TRACE("v"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); + shader_dump_arr_entry(rel_addr, register_idx, shader_version); break; + case WINED3DSPR_CONST: case WINED3DSPR_CONST2: case WINED3DSPR_CONST3: case WINED3DSPR_CONST4: TRACE("c"); - shader_dump_arr_entry(param, addr_token, shader_get_float_offset(param), input, shader_version); + shader_dump_arr_entry(rel_addr, shader_get_float_offset(register_type, register_idx), shader_version); break; - case WINED3DSPR_TEXTURE: /* vs: case D3DSPR_ADDR */ - TRACE("%c%u", (pshader? 't':'a'), reg); - break; + + case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */ + TRACE("%c%u", (shader_is_pshader_version(shader_version) ? 't' : 'a'), register_idx); + break; + case WINED3DSPR_RASTOUT: - TRACE("%s", rastout_reg_names[reg]); + TRACE("%s", rastout_reg_names[register_idx]); break; + case WINED3DSPR_COLOROUT: - TRACE("oC%u", reg); + TRACE("oC%u", register_idx); break; + case WINED3DSPR_DEPTHOUT: TRACE("oDepth"); break; + case WINED3DSPR_ATTROUT: - TRACE("oD%u", reg); + TRACE("oD%u", register_idx); break; - case WINED3DSPR_TEXCRDOUT: + case WINED3DSPR_TEXCRDOUT: /* Vertex shaders >= 3.0 use general purpose output registers * (WINED3DSPR_OUTPUT), which can include an address token */ - - if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) { + if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) + { TRACE("o"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); + shader_dump_arr_entry(rel_addr, register_idx, shader_version); + } + else + { + TRACE("oT%u", register_idx); } - else - TRACE("oT%u", reg); break; + case WINED3DSPR_CONSTINT: TRACE("i"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); + shader_dump_arr_entry(rel_addr, register_idx, shader_version); break; + case WINED3DSPR_CONSTBOOL: TRACE("b"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); + shader_dump_arr_entry(rel_addr, register_idx, shader_version); break; + case WINED3DSPR_LABEL: - TRACE("l%u", reg); + TRACE("l%u", register_idx); break; + case WINED3DSPR_LOOP: TRACE("aL"); break; + case WINED3DSPR_SAMPLER: - TRACE("s%u", reg); + TRACE("s%u", register_idx); break; + case WINED3DSPR_MISCTYPE: - if (reg > 1) { - FIXME("Unhandled misctype register %d\n", reg); - } else { - TRACE("%s", misctype_reg_names[reg]); - } + if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx); + else TRACE("%s", misctype_reg_names[register_idx]); break; + case WINED3DSPR_PREDICATE: - TRACE("p%u", reg); + TRACE("p%u", register_idx); break; + default: - TRACE("unhandled_rtype(%#x)", regtype); + TRACE("unhandled_rtype(%#x)", register_type); break; - } - - if (!input) { - /* operand output (for modifiers and shift, see dump_ins_modifiers) */ - - if ((param & WINED3DSP_WRITEMASK_ALL) != WINED3DSP_WRITEMASK_ALL) { - TRACE("."); - if (param & WINED3DSP_WRITEMASK_0) TRACE("%c", swizzle_reg_chars[0]); - if (param & WINED3DSP_WRITEMASK_1) TRACE("%c", swizzle_reg_chars[1]); - if (param & WINED3DSP_WRITEMASK_2) TRACE("%c", swizzle_reg_chars[2]); - if (param & WINED3DSP_WRITEMASK_3) TRACE("%c", swizzle_reg_chars[3]); - } - - } else { - /** operand input */ - DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; + } +} + +static void shader_dump_dst_param(const struct wined3d_shader_dst_param *param, DWORD shader_version) +{ + DWORD write_mask = param->write_mask; + + shader_dump_register(param->register_type, param->register_idx, param->rel_addr, shader_version); + + if (write_mask != WINED3DSP_WRITEMASK_ALL) + { + static const char *write_mask_chars = "xyzw"; + + TRACE("."); + if (write_mask & WINED3DSP_WRITEMASK_0) TRACE("%c", write_mask_chars[0]); + if (write_mask & WINED3DSP_WRITEMASK_1) TRACE("%c", write_mask_chars[1]); + if (write_mask & WINED3DSP_WRITEMASK_2) TRACE("%c", write_mask_chars[2]); + if (write_mask & WINED3DSP_WRITEMASK_3) TRACE("%c", write_mask_chars[3]); + } +} + +static void shader_dump_src_param(const struct wined3d_shader_src_param *param, DWORD shader_version) +{ + DWORD src_modifier = param->modifiers; + DWORD swizzle = param->swizzle; + + if (src_modifier == WINED3DSPSM_NEG + || src_modifier == WINED3DSPSM_BIASNEG + || src_modifier == WINED3DSPSM_SIGNNEG + || src_modifier == WINED3DSPSM_X2NEG + || src_modifier == WINED3DSPSM_ABSNEG) + TRACE("-"); + else if (src_modifier == WINED3DSPSM_COMP) + TRACE("1-"); + else if (src_modifier == WINED3DSPSM_NOT) + TRACE("!"); + + if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG) + TRACE("abs("); + + shader_dump_register(param->register_type, param->register_idx, param->rel_addr, shader_version); + + if (src_modifier) + { + switch (src_modifier) + { + case WINED3DSPSM_NONE: break; + case WINED3DSPSM_NEG: break; + case WINED3DSPSM_NOT: break; + case WINED3DSPSM_BIAS: TRACE("_bias"); break; + case WINED3DSPSM_BIASNEG: TRACE("_bias"); break; + case WINED3DSPSM_SIGN: TRACE("_bx2"); break; + case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break; + case WINED3DSPSM_COMP: break; + case WINED3DSPSM_X2: TRACE("_x2"); break; + case WINED3DSPSM_X2NEG: TRACE("_x2"); break; + case WINED3DSPSM_DZ: TRACE("_dz"); break; + case WINED3DSPSM_DW: TRACE("_dw"); break; + case WINED3DSPSM_ABSNEG: TRACE(")"); break; + case WINED3DSPSM_ABS: TRACE(")"); break; + default: + TRACE("_unknown_modifier(%#x)", src_modifier); + } + } + + if (swizzle != WINED3DSP_NOSWIZZLE) + { + static const char *swizzle_chars = "xyzw"; DWORD swizzle_x = swizzle & 0x03; DWORD swizzle_y = (swizzle >> 2) & 0x03; DWORD swizzle_z = (swizzle >> 4) & 0x03; DWORD swizzle_w = (swizzle >> 6) & 0x03; - if (0 != modifier) { - switch (modifier) { - case WINED3DSPSM_NONE: break; - case WINED3DSPSM_NEG: break; - case WINED3DSPSM_NOT: break; - case WINED3DSPSM_BIAS: TRACE("_bias"); break; - case WINED3DSPSM_BIASNEG: TRACE("_bias"); break; - case WINED3DSPSM_SIGN: TRACE("_bx2"); break; - case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break; - case WINED3DSPSM_COMP: break; - case WINED3DSPSM_X2: TRACE("_x2"); break; - case WINED3DSPSM_X2NEG: TRACE("_x2"); break; - case WINED3DSPSM_DZ: TRACE("_dz"); break; - case WINED3DSPSM_DW: TRACE("_dw"); break; - case WINED3DSPSM_ABSNEG: TRACE(")"); break; - case WINED3DSPSM_ABS: TRACE(")"); break; - default: - TRACE("_unknown_modifier(%#x)", modifier); - } + if (swizzle_x == swizzle_y + && swizzle_x == swizzle_z + && swizzle_x == swizzle_w) + { + TRACE(".%c", swizzle_chars[swizzle_x]); } - - /** - * swizzle bits fields: - * RRGGBBAA - */ - if (swizzle != WINED3DSP_NOSWIZZLE) + else { - if (swizzle_x == swizzle_y && - swizzle_x == swizzle_z && - swizzle_x == swizzle_w) { - TRACE(".%c", swizzle_reg_chars[swizzle_x]); - } else { - TRACE(".%c%c%c%c", - swizzle_reg_chars[swizzle_x], - swizzle_reg_chars[swizzle_y], - swizzle_reg_chars[swizzle_z], - swizzle_reg_chars[swizzle_w]); - } + TRACE(".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y], + swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]); } } } @@ -1001,21 +1188,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, } /* Destination token */ - if (ins.dst_count) - { - DWORD param, addr_param; - pToken += shader_get_param(pToken, shader_version, ¶m, &addr_param); - - if (param & WINED3DSHADER_ADDRMODE_RELATIVE) - { - shader_parse_src_param(addr_param, NULL, &dst_rel_addr); - shader_parse_dst_param(param, &dst_rel_addr, &dst_param); - } - else - { - shader_parse_dst_param(param, NULL, &dst_param); - } - } + if (ins.dst_count) shader_sm1_read_dst_param(&pToken, &dst_param, &dst_rel_addr, shader_version); /* Predication token */ if (ins.predicate) ins.predicate = *pToken++; @@ -1023,17 +1196,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, /* Other source tokens */ for (i = 0; i < ins.src_count; ++i) { - DWORD param, addr_param; - pToken += shader_get_param(pToken, shader_version, ¶m, &addr_param); - if (param & WINED3DSHADER_ADDRMODE_RELATIVE) - { - shader_parse_src_param(addr_param, NULL, &src_rel_addr[i]); - shader_parse_src_param(param, &src_rel_addr[i], &src_param[i]); - } - else - { - shader_parse_src_param(param, NULL, &src_param[i]); - } + shader_sm1_read_src_param(&pToken, &src_param[i], &src_rel_addr[i], shader_version); } /* Call appropriate function for output target */ @@ -1046,12 +1209,12 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, } } -static void shader_dump_ins_modifiers(const DWORD output) +static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst) { - DWORD shift = (output & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - DWORD mmask = output & WINED3DSP_DSTMOD_MASK; + DWORD mmask = dst->modifiers; - switch (shift) { + switch (dst->shift) + { case 0: break; case 13: TRACE("_d8"); break; case 14: TRACE("_d4"); break; @@ -1059,7 +1222,7 @@ static void shader_dump_ins_modifiers(const DWORD output) case 1: TRACE("_x2"); break; case 2: TRACE("_x4"); break; case 3: TRACE("_x8"); break; - default: TRACE("_unhandled_shift(%d)", shift); break; + default: TRACE("_unhandled_shift(%d)", dst->shift); break; } if (mmask & WINED3DSPDM_SATURATE) TRACE("_sat"); @@ -1074,9 +1237,7 @@ static void shader_dump_ins_modifiers(const DWORD output) void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table) { const DWORD* pToken = pFunction; - const SHADER_OPCODE* curOpcode = NULL; DWORD shader_version; - DWORD opcode_token; DWORD i; TRACE("Parsing %p\n", pFunction); @@ -1093,6 +1254,9 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table while (WINED3DVS_END() != *pToken) { + struct wined3d_shader_instruction ins; + UINT param_size; + if (shader_is_comment(*pToken)) /* comment */ { DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT; @@ -1101,128 +1265,136 @@ void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table pToken += comment_len; continue; } - opcode_token = *pToken++; - curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token); - if (!curOpcode) + shader_sm1_read_opcode(&pToken, &ins, ¶m_size, opcode_table, shader_version); + if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) { - int tokens_read; - FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token); - tokens_read = shader_skip_unrecognized(pToken, shader_version); - pToken += tokens_read; + TRACE("Skipping unrecognized instruction.\n"); + pToken += param_size; + continue; + } + + if (ins.handler_idx == WINED3DSIH_DCL) + { + struct wined3d_shader_semantic semantic; + + shader_sm1_read_semantic(&pToken, &semantic); + + shader_dump_decl_usage(&semantic, shader_version); + shader_dump_ins_modifiers(&semantic.reg); + TRACE(" "); + shader_dump_dst_param(&semantic.reg, shader_version); + } + else if (ins.handler_idx == WINED3DSIH_DEF) + { + unsigned int offset = shader_get_float_offset(shader_get_regtype(*pToken), + *pToken & WINED3DSP_REGNUM_MASK); + + TRACE("def c%u = %f, %f, %f, %f", offset, + *(const float *)(pToken + 1), + *(const float *)(pToken + 2), + *(const float *)(pToken + 3), + *(const float *)(pToken + 4)); + pToken += 5; + } + else if (ins.handler_idx == WINED3DSIH_DEFI) + { + TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK, + *(pToken + 1), + *(pToken + 2), + *(pToken + 3), + *(pToken + 4)); + pToken += 5; + } + else if (ins.handler_idx == WINED3DSIH_DEFB) + { + TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK, + *(pToken + 1)? "true": "false"); + pToken += 2; } else { - if (curOpcode->opcode == WINED3DSIO_DCL) - { - DWORD usage = *pToken; - DWORD param = *(pToken + 1); + DWORD param, addr_token = 0; + int tokens_read; - shader_dump_decl_usage(usage, param, shader_version); - shader_dump_ins_modifiers(param); - TRACE(" "); - shader_dump_param(param, 0, 0, shader_version); - pToken += 2; - } - else if (curOpcode->opcode == WINED3DSIO_DEF) + /* Print out predication source token first - it follows + * the destination token. */ + if (ins.predicate) { - unsigned int offset = shader_get_float_offset(*pToken); - - TRACE("def c%u = %f, %f, %f, %f", offset, - *(const float *)(pToken + 1), - *(const float *)(pToken + 2), - *(const float *)(pToken + 3), - *(const float *)(pToken + 4)); - pToken += 5; + struct wined3d_shader_src_param pred; + + shader_parse_src_param(*(pToken + 2), NULL, &pred); + + TRACE("("); + shader_dump_src_param(&pred, shader_version); + TRACE(") "); } - else if (curOpcode->opcode == WINED3DSIO_DEFI) + + /* PixWin marks instructions with the coissue flag with a '+' */ + if (ins.coissue) TRACE("+"); + + TRACE("%s", shader_opcode_names[ins.handler_idx]); + + if (ins.handler_idx == WINED3DSIH_IFC + || ins.handler_idx == WINED3DSIH_BREAKC) { - TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK, - *(pToken + 1), - *(pToken + 2), - *(pToken + 3), - *(pToken + 4)); - pToken += 5; + switch (ins.flags) + { + case COMPARISON_GT: TRACE("_gt"); break; + case COMPARISON_EQ: TRACE("_eq"); break; + case COMPARISON_GE: TRACE("_ge"); break; + case COMPARISON_LT: TRACE("_lt"); break; + case COMPARISON_NE: TRACE("_ne"); break; + case COMPARISON_LE: TRACE("_le"); break; + default: TRACE("_(%u)", ins.flags); + } } - else if (curOpcode->opcode == WINED3DSIO_DEFB) + else if (ins.handler_idx == WINED3DSIH_TEX + && shader_version >= WINED3DPS_VERSION(2,0) + && (ins.flags & WINED3DSI_TEXLD_PROJECT)) { - TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK, - *(pToken + 1)? "true": "false"); - pToken += 2; + TRACE("p"); } - else - { - DWORD param, addr_token = 0; - int tokens_read; - /* Print out predication source token first - it follows - * the destination token. */ - if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) - { - TRACE("("); - shader_dump_param(*(pToken + 2), 0, 1, shader_version); - TRACE(") "); - } - if (opcode_token & WINED3DSI_COISSUE) - { - /* PixWin marks instructions with the coissue flag with a '+' */ - TRACE("+"); - } + /* Destination token */ + if (ins.dst_count) + { + struct wined3d_shader_dst_param dst; + struct wined3d_shader_src_param rel_addr; - TRACE("%s", curOpcode->name); + shader_sm1_read_dst_param(&pToken, &dst, &rel_addr, shader_version); - if (curOpcode->opcode == WINED3DSIO_IFC - || curOpcode->opcode == WINED3DSIO_BREAKC) - { - DWORD op = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT; + shader_dump_ins_modifiers(&dst); + TRACE(" "); + shader_dump_dst_param(&dst, shader_version); + } - switch (op) - { - case COMPARISON_GT: TRACE("_gt"); break; - case COMPARISON_EQ: TRACE("_eq"); break; - case COMPARISON_GE: TRACE("_ge"); break; - case COMPARISON_LT: TRACE("_lt"); break; - case COMPARISON_NE: TRACE("_ne"); break; - case COMPARISON_LE: TRACE("_le"); break; - default: TRACE("_(%u)", op); - } - } - else if (curOpcode->opcode == WINED3DSIO_TEX - && shader_version >= WINED3DPS_VERSION(2,0) - && (opcode_token & (WINED3DSI_TEXLD_PROJECT << WINED3D_OPCODESPECIFICCONTROL_SHIFT))) - { - TRACE("p"); - } + /* Predication token - already printed out, just skip it */ + if (ins.predicate) ++pToken; - /* Destination token */ - if (curOpcode->dst_token) - { - tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token); - pToken += tokens_read; + /* Other source tokens */ + for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i) + { + struct wined3d_shader_src_param src, rel_addr; - shader_dump_ins_modifiers(param); - TRACE(" "); - shader_dump_param(param, addr_token, 0, shader_version); - } + tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token); + pToken += tokens_read; - /* Predication token - already printed out, just skip it */ - if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) + if (param & WINED3DSHADER_ADDRMODE_RELATIVE) { - pToken++; + shader_parse_src_param(addr_token, NULL, &rel_addr); + shader_parse_src_param(param, &rel_addr, &src); } - - /* Other source tokens */ - for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i) + else { - tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token); - pToken += tokens_read; - - TRACE((i == 0)? " " : ", "); - shader_dump_param(param, addr_token, 1, shader_version); + shader_parse_src_param(param, NULL, &src); } + + TRACE(!i ? " " : ", "); + shader_dump_src_param(&src, shader_version); } - TRACE("\n"); } + TRACE("\n"); } } diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index b68dcf7c6cf..8f68f5d659b 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -590,7 +590,8 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) const BYTE *buffer_get_sysmem(struct wined3d_buffer *This) { - if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) return This->resource.allocatedMemory; + /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */ + if(This->resource.allocatedMemory) return This->resource.allocatedMemory; This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT); This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); @@ -951,12 +952,18 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, { if(count == 1) { + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); } + + ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); + ENTER_GL(); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); + LEAVE_GL(); } } else @@ -987,12 +994,19 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) { + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); } + + ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); + ENTER_GL(); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + LEAVE_GL(); + This->resource.allocatedMemory = NULL; } else if (This->flags & WINED3D_BUFFER_HASDESC) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 253afa884a4..ad0aa187209 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); buffer_object = 0; - data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot])->resource.allocatedMemory; + data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]); if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { FIXME("System memory vertex data load offset is negative!\n"); @@ -4208,12 +4208,13 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) { } static void device_map_psamplers(IWineD3DDeviceImpl *This) { - const DWORD *sampler_tokens = - ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.samplers; + const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = + ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type; unsigned int i; for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) { - if (sampler_tokens[i] && This->texUnitMap[i] != i) { + if (sampler_type[i] && This->texUnitMap[i] != i) + { device_map_stage(This, i, i); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i)); if (i < MAX_TEXTURES) { @@ -4250,9 +4251,9 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshad } static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { - const DWORD *vshader_sampler_tokens = - ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.samplers; - const DWORD *pshader_sampler_tokens = NULL; + const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type = + ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type; + const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL; int start = GL_LIMITS(combined_samplers) - 1; int i; @@ -4261,12 +4262,13 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { /* Note that we only care if a sampler is sampled or not, not the sampler's specific type. * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */ - pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers; + pshader_sampler_type = pshader->baseShader.reg_maps.sampler_type; } for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) { int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS; - if (vshader_sampler_tokens[i]) { + if (vshader_sampler_type[i]) + { if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE) { /* Already mapped somewhere */ @@ -4274,7 +4276,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { } while (start >= 0) { - if (device_unit_free_for_vs(This, pshader_sampler_tokens, vshader_sampler_tokens, start)) { + if (device_unit_free_for_vs(This, pshader_sampler_type, vshader_sampler_type, start)) + { device_map_stage(This, vsampler_idx, start); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(vsampler_idx)); @@ -4531,27 +4534,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn ENTER_GL(); if (dest->resource.allocatedMemory == NULL) { - /* This may happen if we do direct locking into a vbo. Unlikely, - * but theoretically possible(ddraw processvertices test) - */ - dest->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), 0, dest->resource.size); - if(!dest->resource.allocatedMemory) { - LEAVE_GL(); - ERR("Out of memory\n"); - return E_OUTOFMEMORY; - } - if (dest->buffer_object) - { - const void *src; - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object)); - checkGLcall("glBindBufferARB"); - src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB)); - if(src) { - memcpy(dest->resource.allocatedMemory, src, dest->resource.size); - } - GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)); - checkGLcall("glUnmapBufferARB"); - } + buffer_get_sysmem(dest); } /* Get a pointer into the destination vbo(create one if none exists) and diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 6a15a48cd6b..02959e0fd23 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2391,6 +2391,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, /* Floating point formats */ case WINED3DFMT_R16_FLOAT: + case WINED3DFMT_R16G16_FLOAT: case WINED3DFMT_R16G16B16A16_FLOAT: if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) { TRACE_(d3d_caps)("[OK]\n"); @@ -2400,6 +2401,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, return FALSE; case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R32G32_FLOAT: case WINED3DFMT_R32G32B32A32_FLOAT: if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) { TRACE_(d3d_caps)("[OK]\n"); @@ -2408,15 +2410,6 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, TRACE_(d3d_caps)("[FAILED]\n"); return FALSE; - case WINED3DFMT_R16G16_FLOAT: - case WINED3DFMT_R32G32_FLOAT: - if(GL_SUPPORT(ARB_TEXTURE_RG)) { - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - } - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support * instancing. To query if the card supports instancing CheckDeviceFormat with the special format * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value. @@ -3907,6 +3900,8 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) { while(glGetError()); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); checkGLcall("Specifying the PBO test texture\n"); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 35adc50f836..3fd950022df 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -558,16 +558,12 @@ static void shader_glsl_load_constants( prog->vuniformF_locations, &priv->vconst_heap, priv->stack, constant_version); /* Load DirectX 9 integer constants/uniforms for vertex shader */ - if(vshader->baseShader.uses_int_consts) { - shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, - stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI); - } + shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, stateBlock->vertexShaderConstantI, + stateBlock->changed.vertexShaderConstantsI & vshader->baseShader.reg_maps.integer_constants); /* Load DirectX 9 boolean constants/uniforms for vertex shader */ - if(vshader->baseShader.uses_bool_consts) { - shader_glsl_load_constantsB(vshader, gl_info, programId, - stateBlock->vertexShaderConstantB, stateBlock->changed.vertexShaderConstantsB); - } + shader_glsl_load_constantsB(vshader, gl_info, programId, stateBlock->vertexShaderConstantB, + stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants); /* Upload the position fixup params */ GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0])); @@ -583,16 +579,12 @@ static void shader_glsl_load_constants( prog->puniformF_locations, &priv->pconst_heap, priv->stack, constant_version); /* Load DirectX 9 integer constants/uniforms for pixel shader */ - if(pshader->baseShader.uses_int_consts) { - shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, - stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI); - } + shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, stateBlock->pixelShaderConstantI, + stateBlock->changed.pixelShaderConstantsI & pshader->baseShader.reg_maps.integer_constants); /* Load DirectX 9 boolean constants/uniforms for pixel shader */ - if(pshader->baseShader.uses_bool_consts) { - shader_glsl_load_constantsB(pshader, gl_info, programId, - stateBlock->pixelShaderConstantB, stateBlock->changed.pixelShaderConstantsB); - } + shader_glsl_load_constantsB(pshader, gl_info, programId, stateBlock->pixelShaderConstantB, + stateBlock->changed.pixelShaderConstantsB & pshader->baseShader.reg_maps.boolean_constants); /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from. * It can't be 0 for a valid texbem instruction. @@ -724,21 +716,53 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s /* Declare the constants (aka uniforms) */ if (This->baseShader.limits.constant_float > 0) { unsigned max_constantsF; + /* Unless the shader uses indirect addressing, always declare the maximum array size and ignore that we need some + * uniforms privately. E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup and immediate values, still + * declare VC[256]. If the shader needs more uniforms than we have it won't work in any case. If it uses less, the + * compiler will figure out which uniforms are really used and strip them out. This allows a shader to use c255 on + * a dx9 card, as long as it doesn't also use all the other constants. + * + * If the shader uses indirect addressing the compiler must assume that all declared uniforms are used. In this case, + * declare only the amount that we're assured to have. + * + * Thus we run into problems in these two cases: + * 1) The shader really uses more uniforms than supported + * 2) The shader uses indirect addressing, less constants than supported, but uses a constant index > #supported consts + */ if(pshader) { - max_constantsF = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2; - max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF); + /* No indirect addressing here */ + max_constantsF = GL_LIMITS(pshader_constantsF); } else { - /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ - max_constantsF = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1; - max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF); + if(This->baseShader.reg_maps.usesrelconstF) { + /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix). + * Subtract another uniform for immediate values, which have to be loaded via uniform by the driver as well. + * The shader code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex shader code, so one vec4 should be enough + * (Unfortunately the Nvidia driver doesn't store 128 and -128 in one float + */ + max_constantsF = GL_LIMITS(vshader_constantsF) - 3; + max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants); + /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly, + * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but + * for now take this into account when calculating the number of available constants + */ + max_constantsF -= count_bits(This->baseShader.reg_maps.boolean_constants); + /* Set by driver quirks in directx.c */ + max_constantsF -= GLINFO_LOCATION.reserved_glsl_constants; + } else { + max_constantsF = GL_LIMITS(vshader_constantsF); + } } + max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF); shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF); } - if (This->baseShader.limits.constant_int > 0) + /* Always declare the full set of constants, the compiler can remove the unused ones because d3d doesn't(yet) + * support indirect int and bool constant addressing. This avoids problems if the app uses e.g. i0 and i9. + */ + if (This->baseShader.limits.constant_int > 0 && This->baseShader.reg_maps.integer_constants) shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int); - if (This->baseShader.limits.constant_bool > 0) + if (This->baseShader.limits.constant_bool > 0 && This->baseShader.reg_maps.boolean_constants) shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool); if(!pshader) { @@ -810,11 +834,10 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s /* Declare texture samplers */ for (i = 0; i < This->baseShader.limits.sampler; i++) { - if (reg_maps->samplers[i]) { - - DWORD stype = reg_maps->samplers[i] & WINED3DSP_TEXTURETYPE_MASK; - switch (stype) { - + if (reg_maps->sampler_type[i]) + { + switch (reg_maps->sampler_type[i]) + { case WINED3DSTT_1D: shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); break; @@ -843,7 +866,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s break; default: shader_addline(buffer, "uniform unsupported_sampler %csampler%u;\n", prefix, i); - FIXME("Unrecognized sampler type: %#x\n", stype); + FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]); break; } } @@ -2336,11 +2359,29 @@ static void shader_glsl_rep(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; glsl_src_param_t src0_param; + const DWORD *control_values = NULL; + const local_constant *constant; - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); - shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n", - shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth, - src0_param.param_str, shader->baseShader.cur_loop_depth); + /* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */ + if(ins->src[0].register_type == WINED3DSPR_CONSTINT) { + LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) { + if(constant->idx == ins->src[0].register_idx) { + control_values = constant->value; + break; + } + } + } + + if(control_values) { + shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n", + shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth, + control_values[0], shader->baseShader.cur_loop_depth); + } else { + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param); + shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n", + shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth, + src0_param.param_str, shader->baseShader.cur_loop_depth); + } shader->baseShader.cur_loop_depth++; } @@ -2416,7 +2457,7 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins) DWORD shader_version = ins->ctx->reg_maps->shader_version; glsl_sample_function_t sample_function; DWORD sample_flags = 0; - DWORD sampler_type; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask = 0, swizzle; @@ -2424,7 +2465,7 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins) * 2.0+: Use provided sampler source. */ if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = ins->dst[0].register_idx; else sampler_idx = ins->src[1].register_idx; - sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if (shader_version < WINED3DPS_VERSION(1,4)) { @@ -2509,7 +2550,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) DWORD swizzle = ins->src[1].swizzle; sampler_idx = ins->src[1].register_idx; - sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { sample_flags |= WINED3D_GLSL_SAMPLE_RECT; @@ -2584,7 +2625,7 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) glsl_sample_function_t sample_function; DWORD sampler_idx = ins->dst[0].register_idx; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - DWORD sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; UINT mask_size; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -2711,7 +2752,7 @@ static void pshader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins DWORD reg = ins->dst[0].register_idx; SHADER_BUFFER *buffer = ins->ctx->buffer; glsl_src_param_t src0_param; - DWORD sampler_type = ins->ctx->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -2732,7 +2773,7 @@ static void pshader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins DWORD reg = ins->dst[0].register_idx; IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state; - DWORD sampler_type = ins->ctx->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -2777,7 +2818,7 @@ static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *in glsl_src_param_t src1_param; SHADER_BUFFER *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; - DWORD stype = ins->ctx->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg]; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_sample_function_t sample_function; @@ -2808,7 +2849,7 @@ static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *i SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; glsl_src_param_t src0_param; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - DWORD sampler_type = ins->ctx->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -2840,7 +2881,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins) IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; glsl_sample_function_t sample_function; glsl_src_param_t coord_param; - DWORD sampler_type; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask; DWORD flags; @@ -2849,7 +2890,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins) sampler_idx = ins->dst[0].register_idx; flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; - sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; /* Dependent read, not valid with conditional NP2 */ shader_glsl_get_sample_function(sampler_type, 0, &sample_function); mask = sample_function.coord_mask; @@ -2912,7 +2953,7 @@ static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) { glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].register_idx; - DWORD sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); @@ -2928,7 +2969,7 @@ static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) { glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].register_idx; - DWORD sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); @@ -2944,7 +2985,7 @@ static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins { glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].register_idx; - DWORD sampler_type = ins->ctx->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; /* Dependent read, not valid with conditional NP2 */ @@ -4117,8 +4158,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info * else pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0); TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff); - /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ - pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1; + pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b. * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed @@ -4136,12 +4176,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info * else pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0); - /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog. - * In theory the texbem instruction may need one more shader constant too. But lets assume - * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card, - * and lets not take away a uniform needlessly from all other shaders. - */ - pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2; + pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF); /* FIXME: The following line is card dependent. -8.0 to 8.0 is the * Direct3D minimum requirement. diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index d1701f5c1a4..6db17689155 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -120,98 +120,99 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* return WINED3D_OK; } -CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { +const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = +{ /* Arithmetic */ - {WINED3DSIO_NOP, "nop", 0, 0, WINED3DSIH_NOP, 0, 0 }, - {WINED3DSIO_MOV, "mov", 1, 2, WINED3DSIH_MOV, 0, 0 }, - {WINED3DSIO_ADD, "add", 1, 3, WINED3DSIH_ADD, 0, 0 }, - {WINED3DSIO_SUB, "sub", 1, 3, WINED3DSIH_SUB, 0, 0 }, - {WINED3DSIO_MAD, "mad", 1, 4, WINED3DSIH_MAD, 0, 0 }, - {WINED3DSIO_MUL, "mul", 1, 3, WINED3DSIH_MUL, 0, 0 }, - {WINED3DSIO_RCP, "rcp", 1, 2, WINED3DSIH_RCP, 0, 0 }, - {WINED3DSIO_RSQ, "rsq", 1, 2, WINED3DSIH_RSQ, 0, 0 }, - {WINED3DSIO_DP3, "dp3", 1, 3, WINED3DSIH_DP3, 0, 0 }, - {WINED3DSIO_DP4, "dp4", 1, 3, WINED3DSIH_DP4, 0, 0 }, - {WINED3DSIO_MIN, "min", 1, 3, WINED3DSIH_MIN, 0, 0 }, - {WINED3DSIO_MAX, "max", 1, 3, WINED3DSIH_MAX, 0, 0 }, - {WINED3DSIO_SLT, "slt", 1, 3, WINED3DSIH_SLT, 0, 0 }, - {WINED3DSIO_SGE, "sge", 1, 3, WINED3DSIH_SGE, 0, 0 }, - {WINED3DSIO_ABS, "abs", 1, 2, WINED3DSIH_ABS, 0, 0 }, - {WINED3DSIO_EXP, "exp", 1, 2, WINED3DSIH_EXP, 0, 0 }, - {WINED3DSIO_LOG, "log", 1, 2, WINED3DSIH_LOG, 0, 0 }, - {WINED3DSIO_EXPP, "expp", 1, 2, WINED3DSIH_EXPP, 0, 0 }, - {WINED3DSIO_LOGP, "logp", 1, 2, WINED3DSIH_LOGP, 0, 0 }, - {WINED3DSIO_DST, "dst", 1, 3, WINED3DSIH_DST, 0, 0 }, - {WINED3DSIO_LRP, "lrp", 1, 4, WINED3DSIH_LRP, 0, 0 }, - {WINED3DSIO_FRC, "frc", 1, 2, WINED3DSIH_FRC, 0, 0 }, - {WINED3DSIO_CND, "cnd", 1, 4, WINED3DSIH_CND, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_CMP, "cmp", 1, 4, WINED3DSIH_CMP, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)}, - {WINED3DSIO_POW, "pow", 1, 3, WINED3DSIH_POW, 0, 0 }, - {WINED3DSIO_CRS, "crs", 1, 3, WINED3DSIH_CRS, 0, 0 }, - {WINED3DSIO_NRM, "nrm", 1, 2, WINED3DSIH_NRM, 0, 0 }, - {WINED3DSIO_SINCOS, "sincos", 1, 4, WINED3DSIH_SINCOS, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)}, - {WINED3DSIO_SINCOS, "sincos", 1, 2, WINED3DSIH_SINCOS, WINED3DPS_VERSION(3,0), -1 }, - {WINED3DSIO_DP2ADD, "dp2add", 1, 4, WINED3DSIH_DP2ADD, WINED3DPS_VERSION(2,0), -1 }, + {WINED3DSIO_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 }, + {WINED3DSIO_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 }, + {WINED3DSIO_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 }, + {WINED3DSIO_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 }, + {WINED3DSIO_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 }, + {WINED3DSIO_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 }, + {WINED3DSIO_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 }, + {WINED3DSIO_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 }, + {WINED3DSIO_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 }, + {WINED3DSIO_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 }, + {WINED3DSIO_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 }, + {WINED3DSIO_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 }, + {WINED3DSIO_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 }, + {WINED3DSIO_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 }, + {WINED3DSIO_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 }, + {WINED3DSIO_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 }, + {WINED3DSIO_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 }, + {WINED3DSIO_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 }, + {WINED3DSIO_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 }, + {WINED3DSIO_DST, 1, 3, WINED3DSIH_DST, 0, 0 }, + {WINED3DSIO_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 }, + {WINED3DSIO_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 }, + {WINED3DSIO_CND, 1, 4, WINED3DSIH_CND, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_CMP, 1, 4, WINED3DSIH_CMP, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)}, + {WINED3DSIO_POW, 1, 3, WINED3DSIH_POW, 0, 0 }, + {WINED3DSIO_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 }, + {WINED3DSIO_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 }, + {WINED3DSIO_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)}, + {WINED3DSIO_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_DP2ADD, 1, 4, WINED3DSIH_DP2ADD, WINED3DPS_VERSION(2,0), -1 }, /* Matrix */ - {WINED3DSIO_M4x4, "m4x4", 1, 3, WINED3DSIH_M4x4, 0, 0 }, - {WINED3DSIO_M4x3, "m4x3", 1, 3, WINED3DSIH_M4x3, 0, 0 }, - {WINED3DSIO_M3x4, "m3x4", 1, 3, WINED3DSIH_M3x4, 0, 0 }, - {WINED3DSIO_M3x3, "m3x3", 1, 3, WINED3DSIH_M3x3, 0, 0 }, - {WINED3DSIO_M3x2, "m3x2", 1, 3, WINED3DSIH_M3x2, 0, 0 }, + {WINED3DSIO_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 }, + {WINED3DSIO_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 }, + {WINED3DSIO_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 }, + {WINED3DSIO_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 }, + {WINED3DSIO_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 }, /* Register declarations */ - {WINED3DSIO_DCL, "dcl", 0, 2, WINED3DSIH_DCL, 0, 0 }, - /* Flow control - requires GLSL or software shaders */ - {WINED3DSIO_REP , "rep", 0, 1, WINED3DSIH_REP, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_ENDREP, "endrep", 0, 0, WINED3DSIH_ENDREP, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_IF, "if", 0, 1, WINED3DSIH_IF, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_IFC, "ifc", 0, 2, WINED3DSIH_IFC, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_ELSE, "else", 0, 0, WINED3DSIH_ELSE, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_ENDIF, "endif", 0, 0, WINED3DSIH_ENDIF, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_BREAK, "break", 0, 0, WINED3DSIH_BREAK, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_BREAKC, "breakc", 0, 2, WINED3DSIH_BREAKC, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_BREAKP, "breakp", 0, 1, WINED3DSIH_BREAKP, 0, 0 }, - {WINED3DSIO_CALL, "call", 0, 1, WINED3DSIH_CALL, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_CALLNZ, "callnz", 0, 2, WINED3DSIH_CALLNZ, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_LOOP, "loop", 0, 2, WINED3DSIH_LOOP, WINED3DPS_VERSION(3,0), -1 }, - {WINED3DSIO_RET, "ret", 0, 0, WINED3DSIH_RET, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DPS_VERSION(3,0), -1 }, - {WINED3DSIO_LABEL, "label", 0, 1, WINED3DSIH_LABEL, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 }, + /* Flow control */ + {WINED3DSIO_REP, 0, 1, WINED3DSIH_REP, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_IF, 0, 1, WINED3DSIH_IF, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_IFC, 0, 2, WINED3DSIH_IFC, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, + {WINED3DSIO_CALL, 0, 1, WINED3DSIH_CALL, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_RET, 0, 0, WINED3DSIH_RET, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3DPS_VERSION(2,1), -1 }, /* Constant definitions */ - {WINED3DSIO_DEF, "def", 1, 5, WINED3DSIH_DEF, 0, 0 }, - {WINED3DSIO_DEFB, "defb", 1, 2, WINED3DSIH_DEFB, 0, 0 }, - {WINED3DSIO_DEFI, "defi", 1, 5, WINED3DSIH_DEFI, 0, 0 }, + {WINED3DSIO_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 }, + {WINED3DSIO_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 }, + {WINED3DSIO_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 }, /* Texture */ - {WINED3DSIO_TEXCOORD, "texcoord", 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXCOORD, "texcrd", 1, 2, WINED3DSIH_TEXCOORD, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_TEXKILL, "texkill", 1, 1, WINED3DSIH_TEXKILL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)}, - {WINED3DSIO_TEX, "tex", 1, 1, WINED3DSIH_TEX, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEX, "texld", 1, 2, WINED3DSIH_TEX, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_TEX, "texld", 1, 3, WINED3DSIH_TEX, WINED3DPS_VERSION(2,0), -1 }, - {WINED3DSIO_TEXBEM, "texbem", 1, 2, WINED3DSIH_TEXBEM, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXBEML, "texbeml", 1, 2, WINED3DSIH_TEXBEML, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2AR, "texreg2ar", 1, 2, WINED3DSIH_TEXREG2AR, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2GB, "texreg2gb", 1, 2, WINED3DSIH_TEXREG2GB, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2RGB, "texreg2rgb", 1, 2, WINED3DSIH_TEXREG2RGB, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2PAD, "texm3x2pad", 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2TEX, "texm3x2tex", 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3PAD, "texm3x3pad", 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3DIFF, "texm3x3diff", 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)}, - {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDP3TEX, "texdp3tex", 1, 2, WINED3DSIH_TEXDP3TEX, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDP3, "texdp3", 1, 2, WINED3DSIH_TEXDP3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3, "texm3x3", 1, 2, WINED3DSIH_TEXM3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDEPTH, "texdepth", 1, 1, WINED3DSIH_TEXDEPTH, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_BEM, "bem", 1, 3, WINED3DSIH_BEM, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_DSX, "dsx", 1, 2, WINED3DSIH_DSX, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_DSY, "dsy", 1, 2, WINED3DSIH_DSY, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_TEXLDD, "texldd", 1, 5, WINED3DSIH_TEXLDD, WINED3DPS_VERSION(2,1), -1 }, - {WINED3DSIO_SETP, "setp", 1, 3, WINED3DSIH_SETP, 0, 0 }, - {WINED3DSIO_TEXLDL, "texldl", 1, 3, WINED3DSIH_TEXLDL, WINED3DPS_VERSION(3,0), -1 }, - {WINED3DSIO_PHASE, "phase", 0, 0, WINED3DSIH_PHASE, 0, 0 }, - {0, NULL, 0, 0, 0, 0, 0 } + {WINED3DSIO_TEXCOORD, 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXCOORD, 1, 2, WINED3DSIH_TEXCOORD, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_TEXKILL, 1, 1, WINED3DSIH_TEXKILL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)}, + {WINED3DSIO_TEX, 1, 1, WINED3DSIH_TEX, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEX, 1, 2, WINED3DSIH_TEX, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_TEX, 1, 3, WINED3DSIH_TEX, WINED3DPS_VERSION(2,0), -1 }, + {WINED3DSIO_TEXBEM, 1, 2, WINED3DSIH_TEXBEM, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXBEML, 1, 2, WINED3DSIH_TEXBEML, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2AR, 1, 2, WINED3DSIH_TEXREG2AR, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2GB, 1, 2, WINED3DSIH_TEXREG2GB, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2RGB, 1, 2, WINED3DSIH_TEXREG2RGB, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2PAD, 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2TEX, 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3PAD, 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3DIFF, 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)}, + {WINED3DSIO_TEXM3x3SPEC, 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3VSPEC, 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3TEX, 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDP3TEX, 1, 2, WINED3DSIH_TEXDP3TEX, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2DEPTH, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDP3, 1, 2, WINED3DSIH_TEXDP3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3, 1, 2, WINED3DSIH_TEXM3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDEPTH, 1, 1, WINED3DSIH_TEXDEPTH, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_BEM, 1, 3, WINED3DSIH_BEM, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_DSX, 1, 2, WINED3DSIH_DSX, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_DSY, 1, 2, WINED3DSIH_DSY, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_TEXLDD, 1, 5, WINED3DSIH_TEXLDD, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 }, + {WINED3DSIO_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_PHASE, 0, 0, WINED3DSIH_PHASE, 0, 0 }, + {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 }, }; static void pshader_set_limits( @@ -313,7 +314,6 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i list_init(&This->baseShader.constantsI); /* Second pass: figure out which registers are used, what the semantics are, etc.. */ - memset(reg_maps, 0, sizeof(shader_reg_maps)); hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction); if (FAILED(hr)) return hr; @@ -374,7 +374,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) { DWORD shader_version = reg_maps->shader_version; - DWORD *samplers = reg_maps->samplers; + WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type; unsigned int i; if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return; @@ -382,12 +382,12 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i) { /* We don't sample from this sampler */ - if (!samplers[i]) continue; + if (!sampler_type[i]) continue; if (!textures[i]) { ERR("No texture bound to sampler %u, using 2D\n", i); - samplers[i] = (0x1 << 31) | WINED3DSTT_2D; + sampler_type[i] = WINED3DSTT_2D; continue; } @@ -397,21 +397,21 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD case GL_TEXTURE_2D: /* We have to select between texture rectangles and 2D textures later because 2.0 and * 3.0 shaders only have WINED3DSTT_2D as well */ - samplers[i] = (1 << 31) | WINED3DSTT_2D; + sampler_type[i] = WINED3DSTT_2D; break; case GL_TEXTURE_3D: - samplers[i] = (1 << 31) | WINED3DSTT_VOLUME; + sampler_type[i] = WINED3DSTT_VOLUME; break; case GL_TEXTURE_CUBE_MAP_ARB: - samplers[i] = (1 << 31) | WINED3DSTT_CUBE; + sampler_type[i] = WINED3DSTT_CUBE; break; default: FIXME("Unrecognized texture type %#x, using 2D\n", IWineD3DBaseTexture_GetTextureDimensions(textures[i])); - samplers[i] = (0x1 << 31) | WINED3DSTT_2D; + sampler_type[i] = WINED3DSTT_2D; } } } @@ -463,7 +463,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp args->np2_fixup = 0; for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) { - if(shader->baseShader.reg_maps.samplers[i] == 0) continue; + if (!shader->baseShader.reg_maps.sampler_type[i]) continue; tex = (IWineD3DBaseTextureImpl *) stateblock->textures[i]; if(!tex) { args->color_fixup[i] = COLOR_FIXUP_IDENTITY; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 05e52b0fbdd..b1fbadf5d11 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3913,7 +3913,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, if (stream_info->elements[i].buffer_object) { vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; - ptr += (long) vb->resource.allocatedMemory; + ptr += (long) buffer_get_sysmem(vb); } if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 35ba9a417e7..9e9d55c5b33 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1795,6 +1795,22 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ *target_bpp = 6; break; + case WINED3DFMT_R16G16_FLOAT: + *convert = CONVERT_R16G16F; + *format = GL_RGB; + *internal = GL_RGB16F_ARB; + *type = GL_HALF_FLOAT_ARB; + *target_bpp = 6; + break; + + case WINED3DFMT_R32G32_FLOAT: + *convert = CONVERT_R32G32F; + *format = GL_RGB; + *internal = GL_RGB32F_ARB; + *type = GL_FLOAT; + *target_bpp = 12; + break; + default: break; } @@ -2123,6 +2139,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI } case CONVERT_G16R16: + case CONVERT_R16G16F: { unsigned int x, y; const WORD *Source; @@ -2136,6 +2153,9 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI WORD red = (*Source++); Dest[0] = green; Dest[1] = red; + /* Strictly speaking not correct for R16G16F, but it doesn't matter because the + * shader overwrites it anyway + */ Dest[2] = 0xffff; Dest += 3; } @@ -2143,6 +2163,26 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI break; } + case CONVERT_R32G32F: + { + unsigned int x, y; + const float *Source; + float *Dest; + for(y = 0; y < height; y++) { + Source = (const float *)(src + y * pitch); + Dest = (float *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) { + float green = (*Source++); + float red = (*Source++); + Dest[0] = green; + Dest[1] = red; + Dest[2] = 1.0; + Dest += 3; + } + } + break; + } + default: ERR("Unsupported conversation type %d\n", convert); } diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index fab0dcaa8f7..b373caa7200 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -34,78 +34,72 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); #define GLINFO_LOCATION ((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info -/* TODO: Vertex and Pixel shaders are almost identical, the only exception being the way that some of the data is looked up or the availability of some of the data i.e. some instructions are only valid for pshaders and some for vshaders -because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't surprise me if the program can be cross compiled using a large body of shared code */ - -CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { - /* This table is not order or position dependent. */ - +/* This table is not order or position dependent. */ +const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = +{ /* Arithmetic */ - {WINED3DSIO_NOP, "nop", 0, 0, WINED3DSIH_NOP, 0, 0 }, - {WINED3DSIO_MOV, "mov", 1, 2, WINED3DSIH_MOV, 0, 0 }, - {WINED3DSIO_MOVA, "mova", 1, 2, WINED3DSIH_MOVA, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_ADD, "add", 1, 3, WINED3DSIH_ADD, 0, 0 }, - {WINED3DSIO_SUB, "sub", 1, 3, WINED3DSIH_SUB, 0, 0 }, - {WINED3DSIO_MAD, "mad", 1, 4, WINED3DSIH_MAD, 0, 0 }, - {WINED3DSIO_MUL, "mul", 1, 3, WINED3DSIH_MUL, 0, 0 }, - {WINED3DSIO_RCP, "rcp", 1, 2, WINED3DSIH_RCP, 0, 0 }, - {WINED3DSIO_RSQ, "rsq", 1, 2, WINED3DSIH_RSQ, 0, 0 }, - {WINED3DSIO_DP3, "dp3", 1, 3, WINED3DSIH_DP3, 0, 0 }, - {WINED3DSIO_DP4, "dp4", 1, 3, WINED3DSIH_DP4, 0, 0 }, - {WINED3DSIO_MIN, "min", 1, 3, WINED3DSIH_MIN, 0, 0 }, - {WINED3DSIO_MAX, "max", 1, 3, WINED3DSIH_MAX, 0, 0 }, - {WINED3DSIO_SLT, "slt", 1, 3, WINED3DSIH_SLT, 0, 0 }, - {WINED3DSIO_SGE, "sge", 1, 3, WINED3DSIH_SGE, 0, 0 }, - {WINED3DSIO_ABS, "abs", 1, 2, WINED3DSIH_ABS, 0, 0 }, - {WINED3DSIO_EXP, "exp", 1, 2, WINED3DSIH_EXP, 0, 0 }, - {WINED3DSIO_LOG, "log", 1, 2, WINED3DSIH_LOG, 0, 0 }, - {WINED3DSIO_EXPP, "expp", 1, 2, WINED3DSIH_EXPP, 0, 0 }, - {WINED3DSIO_LOGP, "logp", 1, 2, WINED3DSIH_LOGP, 0, 0 }, - {WINED3DSIO_LIT, "lit", 1, 2, WINED3DSIH_LIT, 0, 0 }, - {WINED3DSIO_DST, "dst", 1, 3, WINED3DSIH_DST, 0, 0 }, - {WINED3DSIO_LRP, "lrp", 1, 4, WINED3DSIH_LRP, 0, 0 }, - {WINED3DSIO_FRC, "frc", 1, 2, WINED3DSIH_FRC, 0, 0 }, - {WINED3DSIO_POW, "pow", 1, 3, WINED3DSIH_POW, 0, 0 }, - {WINED3DSIO_CRS, "crs", 1, 3, WINED3DSIH_CRS, 0, 0 }, - /* TODO: sng can possibly be performed as - RCP tmp, vec - MUL out, tmp, vec*/ - {WINED3DSIO_SGN, "sgn", 1, 2, WINED3DSIH_SGN, 0, 0 }, - {WINED3DSIO_NRM, "nrm", 1, 2, WINED3DSIH_NRM, 0, 0 }, - {WINED3DSIO_SINCOS, "sincos", 1, 4, WINED3DSIH_SINCOS, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)}, - {WINED3DSIO_SINCOS, "sincos", 1, 2, WINED3DSIH_SINCOS, WINED3DVS_VERSION(3,0), -1 }, + {WINED3DSIO_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 }, + {WINED3DSIO_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 }, + {WINED3DSIO_MOVA, 1, 2, WINED3DSIH_MOVA, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 }, + {WINED3DSIO_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 }, + {WINED3DSIO_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 }, + {WINED3DSIO_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 }, + {WINED3DSIO_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 }, + {WINED3DSIO_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 }, + {WINED3DSIO_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 }, + {WINED3DSIO_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 }, + {WINED3DSIO_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 }, + {WINED3DSIO_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 }, + {WINED3DSIO_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 }, + {WINED3DSIO_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 }, + {WINED3DSIO_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 }, + {WINED3DSIO_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 }, + {WINED3DSIO_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 }, + {WINED3DSIO_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 }, + {WINED3DSIO_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 }, + {WINED3DSIO_LIT, 1, 2, WINED3DSIH_LIT, 0, 0 }, + {WINED3DSIO_DST, 1, 3, WINED3DSIH_DST, 0, 0 }, + {WINED3DSIO_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 }, + {WINED3DSIO_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 }, + {WINED3DSIO_POW, 1, 3, WINED3DSIH_POW, 0, 0 }, + {WINED3DSIO_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 }, + {WINED3DSIO_SGN, 1, 2, WINED3DSIH_SGN, 0, 0 }, + {WINED3DSIO_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 }, + {WINED3DSIO_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)}, + {WINED3DSIO_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3DVS_VERSION(3,0), -1 }, /* Matrix */ - {WINED3DSIO_M4x4, "m4x4", 1, 3, WINED3DSIH_M4x4, 0, 0 }, - {WINED3DSIO_M4x3, "m4x3", 1, 3, WINED3DSIH_M4x3, 0, 0 }, - {WINED3DSIO_M3x4, "m3x4", 1, 3, WINED3DSIH_M3x4, 0, 0 }, - {WINED3DSIO_M3x3, "m3x3", 1, 3, WINED3DSIH_M3x3, 0, 0 }, - {WINED3DSIO_M3x2, "m3x2", 1, 3, WINED3DSIH_M3x2, 0, 0 }, + {WINED3DSIO_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 }, + {WINED3DSIO_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 }, + {WINED3DSIO_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 }, + {WINED3DSIO_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 }, + {WINED3DSIO_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 }, /* Declare registers */ - {WINED3DSIO_DCL, "dcl", 0, 2, WINED3DSIH_DCL, 0, 0 }, + {WINED3DSIO_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 }, /* Constant definitions */ - {WINED3DSIO_DEF, "def", 1, 5, WINED3DSIH_DEF, 0, 0 }, - {WINED3DSIO_DEFB, "defb", 1, 2, WINED3DSIH_DEFB, 0, 0 }, - {WINED3DSIO_DEFI, "defi", 1, 5, WINED3DSIH_DEFI, 0, 0 }, - /* Flow control - requires GLSL or software shaders */ - {WINED3DSIO_REP , "rep", 0, 1, WINED3DSIH_REP, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_ENDREP, "endrep", 0, 0, WINED3DSIH_ENDREP, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_IF, "if", 0, 1, WINED3DSIH_IF, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_IFC, "ifc", 0, 2, WINED3DSIH_IFC, WINED3DVS_VERSION(2,1), -1 }, - {WINED3DSIO_ELSE, "else", 0, 0, WINED3DSIH_ELSE, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_ENDIF, "endif", 0, 0, WINED3DSIH_ENDIF, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_BREAK, "break", 0, 0, WINED3DSIH_BREAK, WINED3DVS_VERSION(2,1), -1 }, - {WINED3DSIO_BREAKC, "breakc", 0, 2, WINED3DSIH_BREAKC, WINED3DVS_VERSION(2,1), -1 }, - {WINED3DSIO_BREAKP, "breakp", 0, 1, WINED3DSIH_BREAKP, 0, 0 }, - {WINED3DSIO_CALL, "call", 0, 1, WINED3DSIH_CALL, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_CALLNZ, "callnz", 0, 2, WINED3DSIH_CALLNZ, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_LOOP, "loop", 0, 2, WINED3DSIH_LOOP, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_RET, "ret", 0, 0, WINED3DSIH_RET, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1 }, - {WINED3DSIO_LABEL, "label", 0, 1, WINED3DSIH_LABEL, WINED3DVS_VERSION(2,0), -1 }, - - {WINED3DSIO_SETP, "setp", 1, 3, WINED3DSIH_SETP, 0, 0 }, - {WINED3DSIO_TEXLDL, "texldl", 1, 3, WINED3DSIH_TEXLDL, WINED3DVS_VERSION(3,0), -1 }, - {0, NULL, 0, 0, 0, 0, 0 } + {WINED3DSIO_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 }, + {WINED3DSIO_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 }, + {WINED3DSIO_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 }, + /* Flow control */ + {WINED3DSIO_REP, 0, 1, WINED3DSIH_REP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_IF, 0, 1, WINED3DSIH_IF, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_IFC, 0, 2, WINED3DSIH_IFC, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, + {WINED3DSIO_CALL, 0, 1, WINED3DSIH_CALL, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_RET, 0, 0, WINED3DSIH_RET, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3DVS_VERSION(2,0), -1 }, + + {WINED3DSIO_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 }, + {WINED3DSIO_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3DVS_VERSION(3,0), -1 }, + {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 }, }; static void vshader_set_limits( @@ -115,9 +109,6 @@ static void vshader_set_limits( This->baseShader.limits.attributes = 16; This->baseShader.limits.packed_input = 0; - /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */ - This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF); - switch (This->baseShader.reg_maps.shader_version) { case WINED3DVS_VERSION(1,0): @@ -129,8 +120,12 @@ static void vshader_set_limits( This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; This->baseShader.limits.label = 0; + /* TODO: vs_1_1 has a minimum of 96 constants. What happens if a vs_1_1 shader is used + * on a vs_3_0 capable card that has 256 constants? + */ + This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF)); break; - + case WINED3DVS_VERSION(2,0): case WINED3DVS_VERSION(2,1): This->baseShader.limits.temporary = 12; @@ -140,6 +135,7 @@ static void vshader_set_limits( This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; This->baseShader.limits.label = 16; + This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF)); break; case WINED3DVS_VERSION(3,0): @@ -150,6 +146,12 @@ static void vshader_set_limits( This->baseShader.limits.packed_output = 12; This->baseShader.limits.sampler = 4; This->baseShader.limits.label = 16; /* FIXME: 2048 */ + /* DX10 cards on Windows advertise a d3d9 constant limit of 256 even though they are capable + * of supporting much more(GL drivers advertise 1024). d3d9.dll and d3d8.dll clamp the + * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 shaders to 256.s + * use constant buffers + */ + This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF)); break; default: This->baseShader.limits.temporary = 12; @@ -159,6 +161,7 @@ static void vshader_set_limits( This->baseShader.limits.packed_output = 0; This->baseShader.limits.sampler = 0; This->baseShader.limits.label = 16; + This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF)); FIXME("Unrecognized vertex shader version %#x\n", This->baseShader.reg_maps.shader_version); } @@ -326,7 +329,6 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader /* Second pass: figure out registers used, semantics, etc.. */ This->min_rel_offset = GL_LIMITS(vshader_constantsF); This->max_rel_offset = 0; - memset(reg_maps, 0, sizeof(shader_reg_maps)); hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps, This->semantics_in, This->semantics_out, pFunction); if (hr != WINED3D_OK) return hr; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 55c5855c6c6..447de85c42c 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -2895,7 +2895,7 @@ typedef void (WINE_GLAPI * PGLFNGETFENCEIVNVPROC) (GLuint, GLenum, GLint *); #ifndef GL_APPLE_fence #define GL_APPLE_fence 1 #define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x84F3 +#define GL_FENCE_APPLE 0x8A0B #endif typedef void (WINE_GLAPI * PGLFNGENFENCESAPPLEPROC) (GLsizei, GLuint *); typedef void (WINE_GLAPI * PGLFNDELETEFENCESAPPLEPROC) (GLuint, const GLuint *); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 65640b343a6..16512cc4532 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -168,9 +168,6 @@ void hash_table_remove(struct hash_table_t *table, void *key); #define MAX_ACTIVE_LIGHTS 8 #define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES -#define MAX_CONST_I 16 -#define MAX_CONST_B 16 - /* Used for CreateStateBlock */ #define NUM_SAVEDPIXELSTATES_R 35 #define NUM_SAVEDPIXELSTATES_T 18 @@ -416,10 +413,10 @@ typedef struct shader_reg_maps char attributes[MAX_ATTRIBS]; /* vertex */ char labels[MAX_LABELS]; /* pixel, vertex */ DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */ + WORD integer_constants; /* MAX_CONST_I, 16 */ + WORD boolean_constants; /* MAX_CONST_B, 16 */ - /* Sampler usage tokens - * Use 0 as default (bit 31 is always 1 on a valid token) */ - DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)]; BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES]; char usesnrm, vpos, usesdsy; char usesrelconstF; @@ -435,7 +432,6 @@ typedef struct shader_reg_maps typedef struct SHADER_OPCODE { unsigned int opcode; - const char *name; char dst_token; CONST UINT num_params; enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; @@ -486,6 +482,7 @@ struct wined3d_shader_semantic { WINED3DDECLUSAGE usage; UINT usage_idx; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type; struct wined3d_shader_dst_param reg; }; @@ -1826,6 +1823,8 @@ typedef enum { CONVERT_V16U16, CONVERT_A4L4, CONVERT_G16R16, + CONVERT_R16G16F, + CONVERT_R32G32F, } CONVERT_TYPES; HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode); @@ -2244,6 +2243,7 @@ BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *dep /* Math utils */ void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2); UINT wined3d_log2i(UINT32 x); +unsigned int count_bits(unsigned int mask); typedef struct local_constant { struct list entry; @@ -2318,7 +2318,6 @@ typedef struct IWineD3DBaseShaderClass UINT functionLength; UINT cur_loop_depth, cur_loop_regno; BOOL load_local_constsF; - BOOL uses_bool_consts, uses_int_consts; /* Type of shader backend */ int shader_mode; diff --git a/dlls/wined3d/wined3d_private_types.h b/dlls/wined3d/wined3d_private_types.h index 9f62a9ca015..30d6900f0f4 100644 --- a/dlls/wined3d/wined3d_private_types.h +++ b/dlls/wined3d/wined3d_private_types.h @@ -31,18 +31,15 @@ #define WINED3DFMT_FLAG_RENDERTARGET 0x10 #define WINED3DFMT_FLAG_FOURCC 0x20 -/** DCL sampler texture type **/ -#define WINED3DSP_TEXTURETYPE_SHIFT 27 -#define WINED3DSP_TEXTURETYPE_MASK 0x78000000 - -typedef enum _WINED3DSAMPLER_TEXTURE_TYPE { - WINED3DSTT_UNKNOWN = 0 << WINED3DSP_TEXTURETYPE_SHIFT, - WINED3DSTT_1D = 1 << WINED3DSP_TEXTURETYPE_SHIFT, - WINED3DSTT_2D = 2 << WINED3DSP_TEXTURETYPE_SHIFT, - WINED3DSTT_CUBE = 3 << WINED3DSP_TEXTURETYPE_SHIFT, - WINED3DSTT_VOLUME = 4 << WINED3DSP_TEXTURETYPE_SHIFT, - - WINED3DSTT_FORCE_DWORD = 0x7FFFFFFF +typedef enum _WINED3DSAMPLER_TEXTURE_TYPE +{ + WINED3DSTT_UNKNOWN = 0, + WINED3DSTT_1D = 1, + WINED3DSTT_2D = 2, + WINED3DSTT_CUBE = 3, + WINED3DSTT_VOLUME = 4, + + WINED3DSTT_FORCE_DWORD = 0x7FFFFFFF } WINED3DSAMPLER_TEXTURE_TYPE; /** Register types **/ diff --git a/dlls/winex11.drv/graphics.c b/dlls/winex11.drv/graphics.c index a44de115643..8d74c7788e3 100644 --- a/dlls/winex11.drv/graphics.c +++ b/dlls/winex11.drv/graphics.c @@ -1082,8 +1082,13 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y ) /* Update the DIBSection from the pixmap */ X11DRV_UnlockDIBSection(physDev, FALSE); + if( physDev->depth > 1) + pixel = X11DRV_PALETTE_ToLogical(pixel); + else + /* monochrome bitmaps return black or white */ + if( pixel) pixel = 0xffffff; + return pixel; - return X11DRV_PALETTE_ToLogical(pixel); } diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index ef1eef10962..db0bf569ebc 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1138,6 +1138,18 @@ static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/ } +static DWORD FTPFILE_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *buffers, + DWORD flags, DWORD_PTR context) +{ + return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength); +} + +static DWORD FTPFILE_ReadFileExW(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSW *buffers, + DWORD flags, DWORD_PTR context) +{ + return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength); +} + static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written) { LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr; @@ -1224,8 +1236,8 @@ static const HANDLEHEADERVtbl FTPFILEVtbl = { FTPFILE_QueryOption, NULL, FTPFILE_ReadFile, - NULL, - NULL, + FTPFILE_ReadFileExA, + FTPFILE_ReadFileExW, FTPFILE_WriteFile, FTPFILE_QueryDataAvailable, NULL diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 3bda5354faa..9b746f50212 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -610,6 +610,13 @@ static BOOL HTTP_HttpAddRequestHeadersW(LPWININETHTTPREQW lpwhr, lpszEnd += 2; /* Jump over \r\n */ } TRACE("interpreting header %s\n", debugstr_w(lpszStart)); + if (*lpszStart == '\0') + { + /* Skip 0-length headers */ + lpszStart = lpszEnd; + bSuccess = TRUE; + continue; + } pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart); if (pFieldAndValue) { @@ -3270,7 +3277,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, if (dwContentLength || strcmpW(lpwhr->lpszVerb, szGET)) { sprintfW(contentLengthStr, szContentLength, dwContentLength); - HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW); + HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_REPLACE); lpwhr->dwBytesToWrite = dwContentLength; } if (lpwhr->lpHttpSession->lpAppInfo->lpszAgent) diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 785a1ef4b01..4bb25e74942 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -3815,6 +3815,25 @@ DWORD WINAPI InternetConfirmZoneCrossingW( HWND hWnd, LPWSTR szUrlPrev, LPWSTR s return ERROR_SUCCESS; } +/*********************************************************************** + * PrivacySetZonePreferenceW (WININET.@) + */ +DWORD WINAPI PrivacySetZonePreferenceW( DWORD zone, DWORD type, DWORD template, LPCWSTR preference ) +{ + FIXME( "%x %x %x %s: stub\n", zone, type, template, debugstr_w(preference) ); + return 0; +} + +/*********************************************************************** + * PrivacyGetZonePreferenceW (WININET.@) + */ +DWORD WINAPI PrivacyGetZonePreferenceW( DWORD zone, DWORD type, LPDWORD template, + LPWSTR preference, LPDWORD length ) +{ + FIXME( "%x %x: stub\n", zone, type ); + return 0; +} + DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags, DWORD_PTR* lpdwConnection, DWORD dwReserved ) { diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index bb701b024b4..e3c33bd8748 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -1274,6 +1274,15 @@ static void HttpHeaders_test(void) strcpy(buffer,"Warning"); ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n"); + /* Ensure that blank headers are ignored and don't cause a failure */ + ok(HttpAddRequestHeaders(hRequest,"\r\nBlankTest:value\r\n\r\n",-1, HTTP_ADDREQ_FLAG_ADD_IF_NEW), "Failed to add header with blank entries in list\n"); + + index = 0; + len = sizeof(buffer); + strcpy(buffer,"BlankTest"); + ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n"); + ok(index == 1, "Index was not incremented\n"); + ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer); ok(InternetCloseHandle(hRequest), "Close request handle failed\n"); done: diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index b4feba3260c..5e1541da5b1 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -692,6 +692,7 @@ static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContai * of the memory mapped file */ if (pHeader->dwFileSize != pContainer->file_size) { + UnmapViewOfFile( pHeader ); URLCacheContainer_CloseIndex(pContainer); error = URLCacheContainer_OpenIndex(pContainer); if (error != ERROR_SUCCESS) diff --git a/dlls/wininet/wininet.spec b/dlls/wininet/wininet.spec index 78b98cc1ac1..61beaf4a325 100644 --- a/dlls/wininet/wininet.spec +++ b/dlls/wininet/wininet.spec @@ -213,8 +213,8 @@ @ stdcall IsUrlCacheEntryExpiredW(wstr long ptr) @ stub LoadUrlCacheContent @ stub ParseX509EncodedCertificateForListBoxEntry -@ stub PrivacyGetZonePreferenceW # (long long ptr ptr ptr) -@ stub PrivacySetZonePreferenceW # (long long long wstr) +@ stdcall PrivacyGetZonePreferenceW(long long ptr ptr ptr) +@ stdcall PrivacySetZonePreferenceW(long long long wstr) @ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long) @ stdcall RegisterUrlCacheNotification(ptr long long long long long) @ stdcall ResumeSuspendedDownload(long long) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 932483325c8..55162602ff7 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3583,13 +3583,149 @@ outofmem: #endif } +static struct WS_addrinfoW *addrinfo_AtoW(const struct WS_addrinfo *ai) +{ + struct WS_addrinfoW *ret; + + if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfoW)))) return NULL; + ret->ai_flags = ai->ai_flags; + ret->ai_family = ai->ai_family; + ret->ai_socktype = ai->ai_socktype; + ret->ai_protocol = ai->ai_protocol; + ret->ai_addrlen = ai->ai_addrlen; + ret->ai_canonname = NULL; + ret->ai_addr = NULL; + ret->ai_next = NULL; + if (ai->ai_canonname) + { + int len = MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0); + if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len))) + { + HeapFree(GetProcessHeap(), 0, ret); + return NULL; + } + MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len); + } + if (ai->ai_addr) + { + if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr)))) + { + HeapFree(GetProcessHeap(), 0, ret->ai_canonname); + HeapFree(GetProcessHeap(), 0, ret); + return NULL; + } + memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr)); + } + return ret; +} + +static struct WS_addrinfoW *addrinfo_list_AtoW(const struct WS_addrinfo *info) +{ + struct WS_addrinfoW *ret, *infoW; + + if (!(ret = infoW = addrinfo_AtoW(info))) return NULL; + while (info->ai_next) + { + if (!(infoW->ai_next = addrinfo_AtoW(info->ai_next))) + { + FreeAddrInfoW(ret); + return NULL; + } + infoW = infoW->ai_next; + info = info->ai_next; + } + return ret; +} + +static struct WS_addrinfo *addrinfo_WtoA(const struct WS_addrinfoW *ai) +{ + struct WS_addrinfo *ret; + + if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_addrinfo)))) return NULL; + ret->ai_flags = ai->ai_flags; + ret->ai_family = ai->ai_family; + ret->ai_socktype = ai->ai_socktype; + ret->ai_protocol = ai->ai_protocol; + ret->ai_addrlen = ai->ai_addrlen; + ret->ai_canonname = NULL; + ret->ai_addr = NULL; + ret->ai_next = NULL; + if (ai->ai_canonname) + { + int len = WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0, NULL, NULL); + if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len))) + { + HeapFree(GetProcessHeap(), 0, ret); + return NULL; + } + WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len, NULL, NULL); + } + if (ai->ai_addr) + { + if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct WS_sockaddr)))) + { + HeapFree(GetProcessHeap(), 0, ret->ai_canonname); + HeapFree(GetProcessHeap(), 0, ret); + return NULL; + } + memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct WS_sockaddr)); + } + return ret; +} + /*********************************************************************** * GetAddrInfoW (WS2_32.@) */ int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res) { - FIXME("empty stub!\n"); - return EAI_FAIL; + int ret, len; + char *nodenameA, *servnameA = NULL; + struct WS_addrinfo *resA, *hintsA = NULL; + + len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL); + if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY; + WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL); + + if (servname) + { + len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL); + if (!(servnameA = HeapAlloc(GetProcessHeap(), 0, len))) + { + HeapFree(GetProcessHeap(), 0, nodenameA); + return EAI_MEMORY; + } + WideCharToMultiByte(CP_ACP, 0, servname, -1, servnameA, len, NULL, NULL); + } + + if (hints) hintsA = addrinfo_WtoA(hints); + ret = WS_getaddrinfo(nodenameA, servnameA, hintsA, &resA); + WS_freeaddrinfo(hintsA); + + if (!ret) + { + *res = addrinfo_list_AtoW(resA); + WS_freeaddrinfo(resA); + } + + HeapFree(GetProcessHeap(), 0, nodenameA); + HeapFree(GetProcessHeap(), 0, servnameA); + return ret; +} + +/*********************************************************************** + * FreeAddrInfoW (WS2_32.@) + */ +void WINAPI FreeAddrInfoW(PADDRINFOW ai) +{ + while (ai) + { + ADDRINFOW *next; + HeapFree(GetProcessHeap(), 0, ai->ai_canonname); + HeapFree(GetProcessHeap(), 0, ai->ai_addr); + next = ai->ai_next; + HeapFree(GetProcessHeap(), 0, ai); + ai = next; + } } int WINAPI WS_getnameinfo(const SOCKADDR *sa, WS_socklen_t salen, PCHAR host, @@ -4559,19 +4695,21 @@ int WINAPI WSARemoveServiceClass(LPGUID info) /*********************************************************************** * inet_ntop (WS2_32.@) */ -PCSTR WINAPI WS_inet_ntop( INT family, PVOID addr, PSTR buffer, size_t len ) +PCSTR WINAPI WS_inet_ntop( INT family, PVOID addr, PSTR buffer, SIZE_T len ) { #ifdef HAVE_INET_NTOP - union generic_unix_sockaddr unix_addr; + struct WS_in6_addr *in6; + struct WS_in_addr *in; + TRACE("family %d, addr (%p), buffer (%p), len %ld\n", family, addr, buffer, len); switch (family) { case WS_AF_INET: - ws_sockaddr_ws2u( addr, sizeof(struct WS_sockaddr_in), &unix_addr ); - return inet_ntop( AF_INET, &unix_addr, buffer, len ); + in = addr; + return inet_ntop( AF_INET, &in->WS_s_addr, buffer, len ); case WS_AF_INET6: - ws_sockaddr_ws2u( addr, sizeof(struct WS_sockaddr_in6), &unix_addr ); - return inet_ntop( AF_INET6, &unix_addr, buffer, len ); + in6 = addr; + return inet_ntop( AF_INET6, in6->WS_s6_addr, buffer, len ); } #else FIXME( "not supported on this platform\n" ); @@ -4784,7 +4922,7 @@ INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len, LPDWORD lenstr ) { DWORD size; - CHAR buffer[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */ + CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ CHAR *p; TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr ); @@ -4793,17 +4931,36 @@ INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len, if (!string || !lenstr) return SOCKET_ERROR; /* sin_family is guaranteed to be the first u_short */ - if (((SOCKADDR_IN *)sockaddr)->sin_family != AF_INET) return SOCKET_ERROR; + switch(((SOCKADDR_IN *)sockaddr)->sin_family) + { + case WS_AF_INET: + sprintf( buffer, "%u.%u.%u.%u:%u", + (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 24 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 16 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 8 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) & 0xff), + ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) ); + + p = strchr( buffer, ':' ); + if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0; + break; - sprintf( buffer, "%u.%u.%u.%u:%u", - (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 24 & 0xff), - (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 16 & 0xff), - (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) >> 8 & 0xff), - (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.WS_s_addr ) & 0xff), - ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) ); + case WS_AF_INET6: + { + struct WS_sockaddr_in6 *sockaddr6 = (LPSOCKADDR_IN6) sockaddr; - p = strchr( buffer, ':' ); - if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0; + if (!WS_inet_ntop(WS_AF_INET6, &sockaddr6->sin6_addr, buffer, sizeof(buffer))) + { + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + break; + } + + default: + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } size = strlen( buffer ) + 1; diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 23aa59c542b..54ffee75f39 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -55,6 +55,10 @@ ok ( cond tmp, msg, GetCurrentThreadId(), err); \ } while (0); +/* Function pointers */ +static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW) = 0; +static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *) = 0; +static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG) = 0; /**************** Structs and typedefs ***************/ @@ -838,6 +842,11 @@ static void Init (void) { WORD ver = MAKEWORD (2, 2); WSADATA data; + HMODULE hws2_32 = GetModuleHandle("ws2_32.dll"); + + pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW"); + pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW"); + pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop"); ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed\n" ); tls = TlsAlloc(); @@ -1263,6 +1272,7 @@ static void test_WSASocket(void) static void test_WSAAddressToStringA(void) { + SOCKET v6 = INVALID_SOCKET; INT ret; DWORD len; int GLE; @@ -1274,6 +1284,19 @@ static void test_WSAAddressToStringA(void) CHAR expect3[] = "0.0.0.0:65535"; CHAR expect4[] = "255.255.255.255:65535"; + SOCKADDR_IN6 sockaddr6; + CHAR address6[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ + + CHAR addr6_1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}; + CHAR addr6_2[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}; + CHAR addr6_3[] = {0x20,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01}; + + CHAR expect6_1[] = "::1"; + CHAR expect6_2[] = "20ab::1"; + CHAR expect6_3[] = "[20ab::2001]:33274"; + CHAR expect6_3_2[] = "[20ab::2001%4660]:33274"; + CHAR expect6_3_3[] = "20ab::2001%4660"; + len = 0; sockaddr.sin_family = AF_INET; @@ -1331,6 +1354,91 @@ static void test_WSAAddressToStringA(void) ok( !strcmp( address, expect4 ), "Expected: %s, got: %s\n", expect4, address ); ok( len == sizeof( expect4 ), "Got size %d\n", len); + + /*check to see it IPv6 is available */ + v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (v6 == INVALID_SOCKET) { + skip("Could not create IPv6 socket (LastError: %d; %d expected if IPv6 not available).\n", + WSAGetLastError(), WSAEAFNOSUPPORT); + goto end; + } + /* Test a short IPv6 address */ + len = sizeof(address6); + + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = 0x0000; + sockaddr6.sin6_scope_id = 0; + memcpy (sockaddr6.sin6_addr.s6_addr, addr6_1, sizeof(addr6_1)); + + ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len ); + ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() ); + ok( !strcmp( address6, expect6_1 ), "Expected: %s, got: %s\n", expect6_1, address6 ); + ok( len == sizeof(expect6_1), "Got size %d\n", len); + + /* Test a longer IPv6 address */ + len = sizeof(address6); + + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = 0x0000; + sockaddr6.sin6_scope_id = 0; + memcpy (sockaddr6.sin6_addr.s6_addr, addr6_2, sizeof(addr6_2)); + + ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len ); + ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() ); + ok( !strcmp( address6, expect6_2 ), "Expected: %s, got: %s\n", expect6_2, address6 ); + ok( len == sizeof(expect6_2), "Got size %d\n", len); + + /* Test IPv6 address and port number */ + len = sizeof(address6); + + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = 0xfa81; + sockaddr6.sin6_scope_id = 0; + memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3)); + + ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len ); + ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() ); + todo_wine + { + ok( !strcmp( address6, expect6_3 ), "Expected: %s, got: %s\n", expect6_3, address6 ); + ok( len == sizeof(expect6_3), "Got size %d\n", len); + } + + /* Test IPv6 address, port number and scope_id */ + len = sizeof(address6); + + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = 0xfa81; + sockaddr6.sin6_scope_id = 0x1234; + memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3)); + + ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len ); + ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() ); + todo_wine + { + ok( !strcmp( address6, expect6_3_2 ), "Expected: %s, got: %s\n", expect6_3_2, address6 ); + ok( len == sizeof(expect6_3_2), "Got size %d\n", len); + } + + /* Test IPv6 address and scope_id */ + len = sizeof(address6); + + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = 0x0000; + sockaddr6.sin6_scope_id = 0x1234; + memcpy (sockaddr6.sin6_addr.s6_addr, addr6_3, sizeof(addr6_3)); + + ret = WSAAddressToStringA( (SOCKADDR*)&sockaddr6, sizeof(sockaddr6), NULL, address6, &len ); + ok( !ret, "WSAAddressToStringA() failed unexpectedly: %d\n", WSAGetLastError() ); + todo_wine + { + ok( !strcmp( address6, expect6_3_3 ), "Expected: %s, got: %s\n", expect6_3_3, address6 ); + ok( len == sizeof(expect6_3_3), "Got size %d\n", len); + } + +end: + if (v6 != INVALID_SOCKET) + closesocket(v6); } static void test_WSAAddressToStringW(void) @@ -1996,6 +2104,64 @@ static void test_inet_addr(void) ok(addr == INADDR_NONE, "inet_addr succeeded unexpectedly\n"); } +static void test_addr_to_print(void) +{ + char dst[16]; + char dst6[64]; + const char * pdst; + struct in_addr in; + struct in6_addr in6; + + u_long addr0_Num = 0x00000000; + PCSTR addr0_Str = "0.0.0.0"; + u_long addr1_Num = 0x20201015; + PCSTR addr1_Str = "21.16.32.32"; + u_char addr2_Num[16] = {0,0,0,0,0,0,0,0,0,0,0xff,0xfe,0xcC,0x98,0xbd,0x74}; + PCSTR addr2_Str = "::fffe:cc98:bd74"; + u_char addr3_Num[16] = {0x20,0x30,0xa4,0xb1}; + PCSTR addr3_Str = "2030:a4b1::"; + + in.s_addr = addr0_Num; + + pdst = inet_ntoa(*((struct in_addr*)&in.s_addr)); + ok(pdst != NULL, "inet_ntoa failed %s\n", dst); + ok(!strcmp(pdst, addr0_Str),"Address %s != %s\n", pdst, addr0_Str); + + /* Test that inet_ntoa and inet_ntop return the same value */ + in.S_un.S_addr = addr1_Num; + pdst = inet_ntoa(*((struct in_addr*)&in.s_addr)); + ok(pdst != NULL, "inet_ntoa failed %s\n", dst); + ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str); + + /* InetNtop became available in Vista and Win2008 */ + if (!pInetNtop) + { + win_skip("InetNtop not present, not executing tests\n"); + return; + } + + pdst = pInetNtop(AF_INET,(void*)&in.s_addr, dst, sizeof(dst)); + ok(pdst != NULL, "InetNtop failed %s\n", dst); + ok(!strcmp(pdst, addr1_Str),"Address %s != %s\n", pdst, addr1_Str); + + /* Test invalid parm conditions */ + pdst = pInetNtop(1, (void*)&in.s_addr, dst, sizeof(dst)); + ok(pdst == NULL, "The pointer should not be returned (%p)\n", pdst); + ok(WSAGetLastError() == WSAEAFNOSUPPORT, "Should be WSAEAFNOSUPPORT\n"); + + /* Test an zero prefixed IPV6 address */ + memcpy(in6.u.Byte, addr2_Num, sizeof(addr2_Num)); + pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6)); + ok(pdst != NULL, "InetNtop failed %s\n", dst6); + ok(!strcmp(pdst, addr2_Str),"Address %s != %s\n", pdst, addr2_Str); + + /* Test an zero suffixed IPV6 address */ + memcpy(in6.s6_addr, addr3_Num, sizeof(addr3_Num)); + pdst = pInetNtop(AF_INET6,(void*)&in6.s6_addr, dst6, sizeof(dst6)); + ok(pdst != NULL, "InetNtop failed %s\n", dst6); + ok(!strcmp(pdst, addr3_Str),"Address %s != %s\n", pdst, addr3_Str); +} + static void test_ioctlsocket(void) { SOCKET sock; @@ -2310,6 +2476,38 @@ static void test_WSASendTo(void) "a successful call to WSASendTo()\n"); } +static void test_GetAddrInfoW(void) +{ + static const WCHAR port[] = {'8','0',0}; + static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; + + int ret; + ADDRINFOW *result, hint; + + if (!pGetAddrInfoW || !pFreeAddrInfoW) + { + win_skip("GetAddrInfoW and/or FreeAddrInfoW not present\n"); + return; + } + + memset(&hint, 0, sizeof(ADDRINFOW)); + + ret = pGetAddrInfoW(NULL, NULL, NULL, &result); + ok(ret == WSAHOST_NOT_FOUND, "got %d expected WSAHOST_NOT_FOUND\n", ret); + + ret = pGetAddrInfoW(localhost, NULL, NULL, &result); + ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); + pFreeAddrInfoW(result); + + ret = pGetAddrInfoW(localhost, port, NULL, &result); + ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); + pFreeAddrInfoW(result); + + ret = pGetAddrInfoW(localhost, port, &hint, &result); + ok(!ret, "GetAddrInfoW failed with %d\n", WSAGetLastError()); + pFreeAddrInfoW(result); +} + /**************** Main program ***************/ START_TEST( sock ) @@ -2343,6 +2541,7 @@ START_TEST( sock ) test_accept(); test_getsockname(); test_inet_addr(); + test_addr_to_print(); test_ioctlsocket(); test_dns(); test_gethostbyname_hack(); @@ -2353,6 +2552,7 @@ START_TEST( sock ) test_WSASendTo(); test_ipv6only(); + test_GetAddrInfoW(); Exit(); } diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec index 74e71be6385..a77c215b849 100644 --- a/dlls/ws2_32/ws2_32.spec +++ b/dlls/ws2_32/ws2_32.spec @@ -50,6 +50,7 @@ 500 stub WEP +@ stdcall FreeAddrInfoW(ptr) @ stdcall GetAddrInfoW(wstr wstr ptr ptr) @ stdcall WSApSetPostRoutine(ptr) @ stdcall WPUCompleteOverlappedRequest(long ptr long long ptr) diff --git a/fonts/tahomabd.sfd b/fonts/tahomabd.sfd index 327f7ec81ca..6689403e945 100644 --- a/fonts/tahomabd.sfd +++ b/fonts/tahomabd.sfd @@ -9745,8 +9745,469 @@ SplineSet 349 0 l 1 EndSplineSet EndChar + +StartChar: uni0492 +Encoding: 1170 1170 417 +Width: 1158 +Flags: HW +HStem: 0 21G<151 349> 1327 166<349 1033> +VStem: 151 198<0 1327> +LayerCount: 2 +Fore +SplineSet +349 0 m 1 + 151 0 l 1 + 150 828 l 1 + 30 828 l 1 + 30 993 l 1 + 150 993 l 1 + 151 1493 l 1 + 590 1493 l 2 + 1033 1493.17 l 1 + 1033 1328 l 25 + 348 1329 l 17 + 348 993 l 1 + 864 993 l 1 + 864 828 l 1 + 348 828 l 1 + 349 0 l 1 +EndSplineSet +EndChar + +StartChar: uni0493 +Encoding: 1171 1171 418 +Width: 1021 +Flags: HW +HStem: 961 159<319 841> +VStem: 136 183<1 961> +LayerCount: 2 +Fore +SplineSet +841 961 m 1 + 319 961 l 1 + 318 702 l 1 + 663 702 l 1 + 663 537 l 1 + 321 537 l 1 + 320 0 l 1 + 136 1 l 1 + 135 537 l 1 + 30 537 l 1 + 30 702 l 1 + 135 702 l 1 + 136 1119 l 1 + 841 1120 l 1 + 841 961 l 1 +EndSplineSet +EndChar + +StartChar: uni049A +Encoding: 1178 1178 419 +Width: 1426 +Flags: HW +HStem: 0 21G<152 350 980 1237> +VStem: 152 198<0 775 824 1489> +LayerCount: 2 +Fore +SplineSet +152 0 m 1 + 152 1489 l 1 + 350 1489 l 1 + 350 824 l 1 + 960 1489 l 1 + 1201 1489 l 1 + 586 824 l 1 + 1128 128 l 5 + 1260 128 l 5 + 1260 -276 l 5 + 1084 -276 l 5 + 1084 0 l 5 + 980 0 l 1 + 350 775 l 1 + 350 0 l 1 + 152 0 l 1 +EndSplineSet +EndChar + +StartChar: uni049B +Encoding: 1179 1179 420 +Width: 1235 +Flags: HW +HStem: 0 21G<136 321 766 1006> 1101 20G<136 321> +VStem: 136 185<0 547 637 1121> +LayerCount: 2 +Fore +SplineSet +136 0 m 1 + 136 1121 l 1 + 321 1121 l 1 + 321 637 l 1 + 746 1120 l 1 + 981 1120 l 1 + 540 609 l 1 + 906 126 l 1 + 1044 126 l 1 + 1044 -273 l 1 + 870 -273 l 1 + 870 0 l 1 + 766 0 l 1 + 321 547 l 1 + 321 0 l 1 + 136 0 l 1 +EndSplineSet +EndChar + +StartChar: uni04A2 +Encoding: 1186 1186 421 +Width: 1565 +Flags: HW +HStem: 0 21G<152 350 1035 1233> 729 176<350 1035> +VStem: 152 198<0 729 905 1489> 1035 198<0 729 905 1489> +LayerCount: 2 +Fore +SplineSet +152 0 m 1 + 152 1489 l 1 + 350 1489 l 1 + 350 905 l 1 + 1035 905 l 1 + 1035 1489 l 1 + 1233 1489 l 1 + 1232 128 l 1 + 1432 128 l 1 + 1432 -284 l 1 + 1264 -284 l 1 + 1264 0 l 1 + 1035 0 l 1 + 1035 729 l 1 + 350 729 l 1 + 350 0 l 1 + 152 0 l 1 +1035 729 m 1 + 350 729 l 1 + 350 0 l 1 + 152 0 l 1 + 152 1489 l 1 + 350 1489 l 1 + 350 905 l 1 + 1035 905 l 1 + 1035 1489 l 1 + 1233 1489 l 1 +EndSplineSet +EndChar + +StartChar: uni04A3 +Encoding: 1187 1187 422 +Width: 1330 +Flags: HW +HStem: 0 21G<827 1011> 542 142<319 828> 1100 20G<827 1011> +VStem: 137 182<1 542 684 1117> 828 183<0 542 684 1120> +LayerCount: 2 +Fore +SplineSet +828 684 m 1 + 319 684 l 1 + 321 1117 l 1 + 137 1117 l 1 + 136 1 l 1 + 320 0 l 1 + 319 542 l 1 + 828 542 l 1 + 827 0 l 1 + 1036 0 l 1 + 1036 -280 l 1 + 1212 -280 l 1 + 1212 124 l 1 + 1012 124 l 1 + 1011 1120 l 1 + 827 1120 l 1 + 828 684 l 1 +EndSplineSet +EndChar + +StartChar: uni04AE +Encoding: 1198 1198 423 +Width: 1373 +Flags: W +HStem: 0 21G<490 693> +VStem: 493 198<0 638> +LayerCount: 2 +Fore +SplineSet +493 638 m 1 + -10 1489 l 1 + 210 1489 l 1 + 594 832 l 1 + 984 1489 l 1 + 1194 1489 l 1 + 691 659 l 1 + 693 0 l 1 + 490 0 l 1 + 493 638 l 1 +EndSplineSet +EndChar + +StartChar: uni04B0 +Encoding: 1200 1200 424 +Width: 1373 +Flags: HW +HStem: 0 21G<490 693> +VStem: 493 198<0 638> +LayerCount: 2 +Fore +SplineSet +488 636 m 1 + -10 1489 l 1 + 210 1489 l 1 + 594 832 l 1 + 984 1489 l 1 + 1194 1489 l 1 + 692 636 l 1 + 692.145 544 l 1 + 996 544 l 1 + 996 364 l 1 + 692.428 364 l 1 + 693 0 l 1 + 490 0 l 1 + 488 364 l 1 + 184 364 l 1 + 184 540 l 1 + 488 540 l 1 + 488 636 l 1 +EndSplineSet +EndChar + +StartChar: uni04AF +Encoding: 1199 1199 425 +Width: 1185 +Flags: HW +HStem: 0 21G<416 584> +VStem: 6 1000<1117 1117> +LayerCount: 2 +Fore +SplineSet +416 0 m 1 + 6 1117 l 1 + 201 1117 l 1 + 512 234 l 1 + 811 1117 l 1 + 1006 1117 l 1 + 584 0 l 1 + 585 -408 l 5 + 417 -408 l 1 + 416 0 l 1 +EndSplineSet +EndChar + +StartChar: uni04B1 +Encoding: 1201 1201 426 +Width: 1185 +Flags: HW +HStem: 0 21G<416 584> +VStem: 6 1000<1117 1117> +LayerCount: 2 +Fore +SplineSet +416 0 m 1 + 6 1117 l 1 + 201 1117 l 1 + 512 234 l 1 + 811 1117 l 1 + 1006 1117 l 1 + 584 0 l 1 + 585 -30 l 1 + 783 -30 l 1 + 783 -192 l 1 + 585 -192 l 1 + 585 -408 l 1 + 417 -408 l 1 + 417 -192 l 1 + 216 -192 l 1 + 216 -30 l 1 + 417 -30 l 1 + 416 0 l 1 +EndSplineSet +EndChar + +StartChar: uni04E8 +Encoding: 1256 1256 427 +Width: 1577 +Flags: HW +HStem: 1345 170<486.673 862.285> +VStem: 66 204<367.578 1031.53> +LayerCount: 2 +Fore +SplineSet +906.5 1494 m 0 + 1451.58 1355.63 1448.32 631.789 1292.5 316 c 0 + 1075.34 -124.11 553.765 -78.9474 334.5 89 c 0 + 230.093 168.971 66 342.532 66 724 c 0 + 66 1078.75 170.663 1495.69 701 1515 c 0 + 772.333 1517.67 840.833 1510.67 906.5 1494 c 0 +280 864 m 5 + 580.859 864 871.141 864 1172 864 c 1 + 1168 1008 1122.62 1085.25 1077.5 1157 c 0 + 992.412 1292.3 869.686 1340.99 715 1345 c 4 + 549.267 1346.58 288 1308 280 864 c 5 +272 700 m 1 + 276 404 405.534 134.658 742 143 c 0 + 803.333 144.333 860.333 157.5 913 182.5 c 0 + 1090.69 266.846 1188 496 1176 700 c 1 + 1176.23 700 271.707 700 272 700 c 1 +EndSplineSet +EndChar + +StartChar: uni04E9 +Encoding: 1257 1257 428 +Width: 1264 +Flags: HW +HStem: -29 156<424.533 686.267> 991 156<427.133 688> +VStem: 57 194<403.867 713.267> 860 195<404.6 711.4> +LayerCount: 2 +Fore +SplineSet +253.356 471.062 m 1 + 260.286 380.31 282.501 327.955 320 266 c 0 + 374.667 173.333 458.333 127 571 127 c 0 + 659.667 126.333 732.667 172.667 790 266 c 0 + 829.765 331.328 849.119 375.661 855 471 c 1 + 854.531 471 546 471 546 471 c 25 + 546 471 252 471 253.356 471.062 c 1 +253.045 633 m 1 + 252 633 528 633 528 633 c 25 + 528 633 851.354 632.971 852 633 c 1 + 846.413 729.642 830.177 783.995 790 850 c 0 + 734 943 661 990 571 991 c 0 + 460.333 991 377 944.667 321 852 c 0 + 282.308 788.435 259.656 725.436 253.045 633 c 1 +571 1147 m 0 + 720.333 1146.33 840.333 1089 931 975 c 0 + 1013.67 872.333 1055 733.333 1055 558 c 0 + 1055 382.667 1013.67 243.667 931 141 c 0 + 841 27 721 -29.6667 571 -29 c 0 + 401 -29 271 28 181 142 c 0 + 98.3333 244.667 57 383.667 57 559 c 0 + 57 734.333 98.3333 873.333 181 976 c 0 + 271 1090 401 1147 571 1147 c 0 +EndSplineSet +EndChar + +StartChar: uni04D8 +Encoding: 1240 1240 429 +Width: 1577 +Flags: HW +HStem: 1345 170<486.673 862.285> +VStem: 66 204<367.578 1031.53> +LayerCount: 2 +Fore +SplineSet +362.368 1424 m 1 + 449.203 1476.66 560.072 1509.87 701 1515 c 0 + 772.333 1517.67 840.833 1510.67 906.5 1494 c 0 + 1451.58 1355.63 1448.32 631.789 1292.5 316 c 0 + 1075.34 -124.11 553.765 -78.9474 334.5 89 c 0 + 230.093 168.971 66 342.532 66 724 c 0 + 66 769.956 67.7565 816.956 71.9668 864 c 1 + 1172 864 l 1 + 1168 1008 1122.62 1085.25 1077.5 1157 c 0 + 992.412 1292.3 862.686 1355.99 708 1360 c 0 + 632.688 1360.72 510.037 1326.14 428 1276 c 1 + 429.387 1276 362.368 1424 362.368 1424 c 1 +272 700 m 1 + 276 404 405.534 134.658 742 143 c 0 + 803.333 144.333 860.333 157.5 913 182.5 c 0 + 1090.69 266.846 1188 496 1176 700 c 1 + 1176.23 700 271.707 700 272 700 c 1 +EndSplineSet +EndChar + +StartChar: afii10846 +Encoding: 1241 1241 430 +Width: 1264 +Flags: HW +HStem: -29 156<424.533 686.267> 991 156<427.133 688> +VStem: 57 194<403.867 713.267> 860 195<404.6 711.4> +LayerCount: 2 +Fore +SplineSet +253.356 456.062 m 1 + 252 456 546 456 546 456 c 25 + 546 456 854.531 456 855 456 c 1 + 849.119 360.661 829.765 331.328 790 266 c 0 + 732.667 172.667 659.667 126.333 571 127 c 0 + 458.333 127 374.667 173.333 320 266 c 0 + 282.501 327.955 260.286 365.31 253.356 456.062 c 1 +390.296 932.633 m 17 + 439.053 971.544 499.288 991 571 991 c 0 + 661 990 734 943 790 850 c 0 + 830.177 783.995 846.413 714.642 852 618 c 1 + 851.354 617.971 528 618 528 618 c 25 + 528 618 55.9561 618 57 618 c 1 + 57 618 57 558 57 559 c 1 + 57 383.667 98.3333 244.667 181 142 c 0 + 271 28 401 -29 571 -29 c 0 + 721 -29.6667 841 27 931 141 c 0 + 1013.67 243.667 1055 382.667 1055 558 c 0 + 1055 733.333 1013.67 872.333 931 975 c 0 + 840.333 1089 720.333 1146.33 571 1147 c 0 + 467.901 1147 394.675 1124.93 321 1083 c 1 + 321.162 1081.89 390.296 932.633 390.296 932.633 c 17 +EndSplineSet +EndChar + +StartChar: uni04BA +Encoding: 1210 1210 431 +Width: 1311 +Flags: HW +HStem: 0 21G<135 320 826 1010> 987 160<506.667 801.333> +VStem: 135 185<0 769.933 946 1556> 826 184<0 944.733> +LayerCount: 2 +Fore +SplineSet +1119 557 m 2 + 1120 0 l 1 + 936 0 l 1 + 935 551 l 2 + 935 762.333 763.333 868 640 868 c 0 + 536.667 868 456.333 834.333 399 767 c 0 + 345.667 703.667 319 619.333 319 514 c 2 + 320 0 l 1 + 135 0 l 1 + 135 1496 l 1 + 320 1496 l 1 + 319 827 l 1 + 405.667 961 526.333 1028 681 1028 c 0 + 899.667 1028 1119 871 1119 557 c 2 +EndSplineSet +EndChar + +StartChar: uni04BB +Encoding: 1211 1211 432 +Width: 1311 +Flags: HW +HStem: 0 21G<135 320 826 1010> 987 160<506.667 801.333> +VStem: 135 185<0 769.933 946 1556> 826 184<0 944.733> +LayerCount: 2 +Fore +SplineSet +1063 461 m 2 + 1064 0 l 1 + 880 0 l 1 + 879 455 l 2 + 879 666.333 763.333 772 640 772 c 0 + 536.667 772 456.333 738.333 399 671 c 0 + 345.667 607.667 319 523.333 319 418 c 2 + 320 0 l 1 + 135 0 l 1 + 135 1376 l 1 + 320 1376 l 1 + 319 731 l 1 + 405.667 865 526.333 932 681 932 c 0 + 899.667 932 1063 775 1063 461 c 2 +EndSplineSet +EndChar EndChars -BitmapFont: 11 417 9 2 1 FontForge +BitmapFont: 11 433 9 2 1 FontForge BDFStartProperties: 36 FONT 1 "-FontForge-Tahoma-Normal-R-Normal--11-80-96-96-P-62-ISO10646-1" FONTBOUNDINGBOX 1 "15 11 0 -2" @@ -10616,8 +11077,40 @@ BDFChar: 415 1169 5 0 4 0 6 #l)3N^qd_c BDFChar: 416 1168 6 0 4 0 8 #l)3N^qdb$^]4?7 +BDFChar: 417 1170 6 -1 4 0 7 +Hsg@W?smAM +BDFChar: 418 1171 5 -1 4 0 5 +Hsl_W?sis7 +BDFChar: 419 1178 7 0 6 -1 7 +bh2FCi:,CE!WW3# +BDFChar: 420 1179 7 0 5 -1 5 +bh2F;fZXHu +BDFChar: 421 1186 8 0 7 -1 7 +`l?$t`l?$=!<<*" +BDFChar: 422 1187 7 0 6 -1 5 +bfp"/bg$7i +BDFChar: 423 1198 7 0 5 0 7 +bfk`5_+AMJ3a.MJ3\WM5_(!X*WQ0? +BDFChar: 428 1257 8 0 6 0 7 +3(/AtJq?BM +BDFChar: 429 1240 11 0 9 0 10 +*WR>`!.Y&7!'pS"J3\WM5_(!X*WQ0? +BDFChar: 430 1241 8 0 6 0 7 +3!9<^Jq?BM +BDFChar: -1 1242 15 0 0 0 0 +z +BDFChar: 431 1210 8 0 7 0 10 +J:N0#]Y]5NJUr@P +BDFChar: 432 1211 8 0 6 0 8 +J:N0__LdAkJcGcN EndBitmapFont -BitmapFont: 16 417 13 3 1 FontForge +BitmapFont: 16 433 13 3 1 FontForge BDFStartProperties: 36 FONT 1 "-FontForge-Tahoma-Normal-R-Normal--16-120-96-96-P-93-ISO10646-1" FONTBOUNDINGBOX 1 "21 16 0 -3" @@ -13280,5 +13871,37 @@ BDFChar: 415 1169 8 1 5 0 9 #l&q#J:N0#J:IV" BDFChar: 416 1168 9 0 6 0 12 !rd_#J:N0#J:N0#J,fQL +BDFChar: 417 1170 9 -1 6 0 11 +Im?7ar]i_65X7S" +BDFChar: 418 1171 8 0 5 0 8 +HpBsl5X7S"5QCca +BDFChar: 419 1178 9 0 8 -2 11 +JH19%KE-f.O8tpRhuJi=L]E).JcL@P!.Y'" +BDFChar: 420 1179 10 0 7 -2 8 +KSY__i/ibJK)kuQ +BDFChar: 421 1186 11 0 10 -2 11 +J3\WMJ3\WMJ3a.MJ3\WMJ3\WMJ3\Wm!$D7a +BDFChar: 422 1187 10 1 8 -2 8 +JqAT+rdo`RK)kuQ +BDFChar: 423 1198 10 0 8 0 11 +J:Koc5l`)/'EAgI#QP,1#QP,1#QP,1 +BDFChar: 424 1200 10 0 8 0 11 +J:Koc5l`)/'EB*Q#QT>S#QP,1#QP,1 +BDFChar: 425 1199 8 0 6 -3 8 +Jq?BY6msGp&.fBa +BDFChar: 426 1201 8 0 6 -3 8 +Jq?BY6msGpHk6i# +BDFChar: 427 1256 12 0 10 0 11 +*rmF65X9iBJ0=mMJ09@bJ07*B+FkO6 +BDFChar: 428 1257 9 0 7 0 8 +4@4UMs+,_f49,?] +BDFChar: 429 1240 12 0 10 0 11 +*rmF6!'gN,!$M="J09@bJ07*B+FkO6 +BDFChar: 430 1241 9 0 7 0 8 +49>Nas+,_f49,?] +BDFChar: 431 1210 9 0 8 0 11 +J,k*"J,k*"^&YtLJ:N0#J:N0#J:N0# +BDFChar: 432 1211 9 0 7 0 9 +J:N0__L[8hJUme$ EndBitmapFont EndSplineFont diff --git a/fonts/tahomabd.ttf b/fonts/tahomabd.ttf index 091174b116711dd83746d4880d8abdfb3c986046..3daab9dfbbba0c8003cb9692fd165f38e56e7cd3 100644 GIT binary patch delta 7312 zcwUuQ3tUvyy8pgCd+&MhngIbHyap5`g@Azpj1W*vt!|p+wbTNiXg<@73LSiN5fmK} z1RqFRnr0-P(6X*Z2lX7S)8lmXS6%Q});-5#RvxdNn3?w2~XsW*gB>O4|)ygfyMKemb}}!!$Krr4f))>h0}}r z9!Pr%_62qlX^Q6;l`Ikj{sj}@6-6y5nm=>TtG}H>wB87#MlD*nWa)b?-`-DDGl|F$ z0e_WGZpH^Er`RX)WBL|_!!3NMrI`!m9B~~*XdDzFZJ|2xGb)$EsZL6va%rmTrnraX zo;H%!E0E(UPrObUYMa?&)YZzNU8Hd@6h&)xe-La!%YlppKbH~Px4IQ?Q=^c-BjQR3g`AuRw8w>45V{l86aV*=m z(DO8#ifJBirI%?hEujV6KrhmKK13U6Cm*0?{01MUx%3k6;l2C{59QZsA=zN~L3)qY z&@5Wa`#G8qauY40GOnSSw3f=Lo;56T1#jR@T+NkSMJM=8`j7`8qT9Ka>$sWUGO(RW zc_VM;Z7r#R7LDy#!WRiQ6GIa75~n4WCT>kUmU!WQ;r`hBmnD@ZeVV)?xiYyv`B3tS zr>VR)(UH#b-(qf z^`rFu=@Zj8rXNlJH2qqJE+ZvlQpOAtlw4>@M!}G_r9F7)WE(}GI`z^QZ(3qN7WbwU2M?V`uX|Bo*^CW5h!8gO6qn#5Hm5*@HA= z95U@Y7 zR2(jLju4BSVSL%i&T!{qHVH9~ua)@%4ERQ>g8>0H>gQ2mHd!=o73i@Ujhh8)-e~7D z`@cm1-f&E4S4h}&Oc?!-H=Q#$Ot|QXQ{dsb4f|d^fv5y1Q3;CCglfzhMLi;`$#QCh zV+aa6_><-{d`vjRZ~6VYmxTz&pPk?HR?Ro|t#Ro#*;%Z)CQcCDG`GB47|^La%NJ)#BqH5IIsG?pnmzo zLW1KnA@1Q75691ZW|zZhlP)->pUrx%m3ov8mI^6IRT_JT&JZyUDl4b=C_MNXpLbgL z^tRWa%=xrb=y>_;&q~JgT$iL`=_(DPWN5OcTSFrxf7beI5;<<5DK*`kD8$9a#mZV+ zN^G1aLX&Py&lci%ZpGPWr_E@bJJzfXxi2Dh=i&F>+MeOOA&ZX)k>;?{o5Py2P%Y02 z)_KQXn)2Ah6`8VBU7!{F^((G;?a14Q>ayl;8{NPEupuAu8)HU{cz$@|Z)HvzGOifIt z5R=I<$=%-}oIJ!eBtJQPkTEpG9FlG|!i{LH|t}ztkV(gY|;V zA8if}= z;zvy$GuC1@c-QS0o|?7W2Zq=ji*}Cq{*f&ff=S zmpySiO#hD>6z=TwuCu%TylTfg30@_n{MhbYHC~NZ=QfE_;1Mi_MHH-mwcr6x>ntxV zU4O}i%2>~T%9)(9fh*GrMmCLpCI$6T#N|l0<0ntnk#yy_b9D(>Vv*4D%c7xS+|m+T zbwh~aCfr2!@;-i*U&HO=0Kbm=$06mW!fz_~3VZ+RNXrp!p-S4#NBKAWHn&n8AESEO zPCxK*euwta7TQ6t(I(nTHFTU#(kXtoWnT4fB%Aj61#^;8GgH*oqPDqeo9AhB)$v?) zJU3r$M|s-3B(+UeTXlY(I)7w_zG&8*Imt;Gsa6jsKf~Q>Qu8zI=55pLE4L-~+d<4b zxe?ctJ-9xx;vD)%_=x??wr92I(|B&S534ovPWzPFaPuydVjl{p)$X<*o)#kSR(VRl z(OzHsomAy&;%fW4x_E7sE1j!d>Gq9#;_V%ES#cGvD&7F7eCRj1u2K-7^yZ>B7glVr z=WS05u5f(<*-y9T~g1 zSf4qd!gU#1F5?btf^-lNi|6+S*G-Hct$$FeaMfYf&H6|EDqO{oEXG>JSZ7>=84}Mm zqy^MCFT+C|1uWPA zRMAMT25Rj8wtKkbw$Hw0w*_?j?p%vo9;l*lNQJxY(;;#f=}FghnvD2A?YfExUWC*| zNCm>HVU6*Aw>iqniyHg+-PY6xoNbNqs%;-OKG;jze^0z>XV#vWgc_F;#X!)i2ILt! zP&MPpfGj?YnTE9%n(d$U3Yj1CN0;gGv>$~=R!_9dYPnPLq%=kEcS5lj=&Mn{F zb#s$1_i#O3owm(4`{S&iwHY#LJ^hn9DA#An8dqD}tSng(&lvvm`A!deR@-g%%L=>Y zhqlc|n_lbEYge3Ff5o?NQlVCMX+5rxkB;=Z_H!4mcV546?ldzT(!!zHRSlMvf{&i` z`nICx3kz=!@LShbmJnkc?K;G-o6uu5LpGNc4tEB~?b(=twX%F8yGlC9GnU+3;yt!}lY6YC>~lHb zpF5}rziql@K!DtqT)g{+bv%M^d~y?oV{-u6}B%U7-HD{D#8I@y;bU)ObJ z(rU^?fef07ExRwjZ?gI5Ts}HmPEL+9$Nf=iR=Zrx&J~S*dW2$CUUZ;AE94s2Yek#R7?tBKajUmPwj!WI)s^9M;)9jS$6XLB1?g&1;i*+VFv2H7m!o5{ z-I6({Jh#(bBN@7YTS?=?)Zvi^F1vHMLK)_;mZ^Wg5oGh#xqS6rVaP#g>UEwt-Q;HJM1`TCTNGjPse$<^3LaCeggg7K_Z z!qFWMUuc83)gyCr8r|_=^0g@r!QX-T1|=Y6UNW6gPLGV2NU18KNAVebt{602cCs+Z zsMMDJc9eW!k#D4EWHM@8oxWT)Shp&m%)QUDa4&MLT$z`p%7mLZr|(@tc`H}Cg=)v^ z`D;Pjr#8vJF@8sUd{9QD^Cgn&Y75;gUtfjgzZb0P+G>T>;OD2Xf>YhBlVFW+2nbME z13pw(xCR9(uYP`xVDMaQbU@`TqvzjM%16TuMkD0e{hy^MJgWt?NjT3%v^ga6k=9fn z4wY@wh>Y`q7lAdv7GM`}05}T#C-6Jqk3c8zH{gGWOweQU2l@a5fM_5dNCI#ZH)R9) zz&KzsFddi!tN_*l8-eXa(@d|TgLiAw2>=V3E&x}68-NRb`T!w-8HfY$Y8r?I0!IPk zfvLbuU;$79tO7Ox^}s&hVC_{Czx*Ibv6&mV0r6X^+?UXnBRYsn;Gfi}$twMIFZy!p z-aro2*uu)x0lfWFm}f9-hZiqgON7s50;mFYX@RFDef& z@)Ygig%9Y_Z|hk!JpJxP!wc@<5hbYnm0tWXV2H{;r1G^Y-O`JG$7^0BFtqh(2oGVK z^3O12TFeBH1aT5D3s?%20m!VVMEf-WI>k2NW1s{0EAS(53qW!u8Sn#8MG_p9P(@NA zFbv28Mgv6vDo0ujpn4*tjh?8+V2~uyzQ;qfB~Mtp&M16R}zLERC)d$8;2^Dp!ZRZ!!Ghu zWjJvu-6M-23f+Ma1pjT`J4g;tj5!+e(0)TVkPhMF^ zU?h~i@}GaHFAxO`1}p&14GHIl^eBKcLwXi~ehDEkNL8MwT87k?NARY5W!aK+r*9T( zFFH%5gQ+J@mRYTZkxG`cpH>Hz5{U8)X0K3rDADfBWH+ijlgFOyx6t?X)8dKWg(P@n z{;0|r+>3d5e^Gh;sAn4v4_0|WN|wzkv)gK~MTbwigGXdl`Q2rxlnxF_N>TYIRlb_l z;ir4iA9>AFs>;$jBSy(GPJR(5zj#K?-c{gNb)SZ*`}09HLr($o0X#jVN}vuv^+-5) zC2R!=fstB)_knf*Yf3m>CFqp?4&b>Z;MNYx5u_%a3nS2T^+6TjKHV!%mqHtMWQkULTJ=kK>6%0RcK(E`G(H zbjwUIt1`+d9-{KP4`*fTB&)n)l^3jJSv_4QRC+BMr}DZ_VZ}I{vNT-f|J0+vldVh- zzhH>USF>7>(u>aYny2U+)_OEv$#ROi*Cwd@tW?e5Zs1Me1K?BOTL6yBC}SBm$;iHp zJtU6+#sYZ0%Qy$*DFF1y*sn77tGpVp19&{j%FX610Dbb80J4u;u_vmNAE+HXga`jG D7UxVC delta 3560 zcwTK*3s98T6+Q?4U07gWycG~IiX!h_YD6%-Z)ysyy_{qi8>{8=UQ7RGeUexJzJO%&WQYvIfJGZ)R?iSe%wRmWR< zh*bS6%S$VxF6dxLcbLfk+RCj}2~?mm5`|(>lGc`PsiY_hz@&P}hP4~Ft=YNs`emYs zi$v?Bvel)lN)LB8z>hf?|4A8$&@tLP$h#qrD=V+6UN_y=OXN3^NZqt?)5_8X2xni^;?9bM*@$`o#2=>9%=_xysya{>pqOJ0v?PyCi#S_D)A} z8}h1>WvxAPflM%s?iQTl<;awnapH|aQ?p#yZ7 zj?k~Ek1lbSqrdrGl^oTwLau2^9o0n4`}iRFVOOxBN-XHx*)I3BY_OtF^Z6wH=PH#= zF9J(RA|0hu0hJ)Hfn=a)-iKZ|#nDbr8$~-j?I_GslaBX`(OrUN)WHG4DgA>_`V>jg zG#Ztn)Ju@udGZTYo!id!^7d27=sk;G_o=m7i+dl}0A41+K8kDPY4*tx7WY-~SGg9b z!?+b~y}a8#KgL2qTmv+?2eC>hcz^eI?9rF+*vE5&9NC(O|0S(cV=V4luyPAEYJ_$e zkmSBcjqZCG?{3XiS=`N-HQ4$R{3wHF8P+PpI>l{?&{*F#S>N#J7Gg5OMi^{0$miO! zplgS&9lE{Hz1=n${Mge+G#2+}@S7p^osPi&wbOZ;$8j{s3GIbGQbl_nR`0>;J?)#p z*MYACpMIuL<&CBKOni(IqZ%;|(p2|JDt6zeZufn}I*9QLXLcDa@Sp~$qXMo68swsm z87hx|@*5py$RBp(89n+y9mPQ_4y@s91fsYB_6FEcL}5CcY<|MTV|N#m266X#Ru4m4 zgtiM-o>&WqrTu4c5&Q!L_f9+hYt)(8e0`-&(%X7QpxmK>|O4HXVvin(7y0?NlyY@vW zCmg36hgdo1JGenP3ywM6ZzVY1{^KEoL*r8G9d`%6F*>g>-wm_fh~#hm)L+{!M)5OR zdvGwLWCK3Kt-8eay@v`3Q7GLwP$jnLXi$w>twM!Yd8lGgS&e$VLXEzxP^kG(b>3<7s;J@H(V`vxAb^W2Clnbg_J^@6q-N%TX+2_iVPkdsEpsm_fF9O`e4 z`Mnr05P5D0495K3hl}%av3`QnLqcG&cs?m8IDj+(4=F_GWC)#LAWU%ig2P78Si!9t zvTq$)G`9XJi=G(95v2+KiVu%xlTrl#Z@~u$`N42G&fjNVJdoYe{Dgac1gltJR0F@y1csC^x2_uyh#F~)%k2fW;*H)0kjkA?x zT@=a65knsfcSKSWe>Xz@T*ylOjuYIE&gcoO_P0*DDF*dGjCXL-L!bD>9;S>IoX+cG z3cgWD6Rajp-~-YMotZ)>$g`N2ds%QkiA(v#ko_l#OOXZX<4DT6VH`XY{B^RV`$ZxKyprJSE}D&e#+rZZ@2gU`I*-l6;ak9Y9dhT;LU-mX9|{=<9bZ{q?zVGE zwvwcIabi%3TNLEHLZ1mqg4-ataIZh}l+RqfK9E9!{)ZFc)#(;G$`u$XxQ_*=6mFK_ z{w25wB}w9Jmqht2Ize#H2~Ke?8JHpXx*-GJ&7Law_XIDJQu4tF`LfSE#ojb$&J-m{ zxE55nzg3d~RG$i0p9)u>3h$>1iB;kBsH%Y-!0P}`xC+;ust>pdeCOSi#a*^LQ+eY5 E0fr0AbpQYW diff --git a/include/commctrl.h b/include/commctrl.h index 4727e3ea31d..a65c9acf011 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -1599,7 +1599,7 @@ CreateToolbar(HWND, DWORD, UINT, INT, HINSTANCE, HWND WINAPI CreateToolbarEx(HWND, DWORD, UINT, INT, - HINSTANCE, UINT, LPCTBBUTTON, + HINSTANCE, UINT_PTR, LPCTBBUTTON, INT, INT, INT, INT, INT, UINT); HBITMAP WINAPI diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 158eb5ed0c5..4041c2c6148 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -93,6 +93,7 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont*, GDIPCONST GpGraphics*, GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont*, REAL, REAL*); /* FontCollection */ +GpStatus WINGDIPAPI GdipNewInstalledFontCollection(GpFontCollection**); GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection**); GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection**); GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection*, GDIPCONST WCHAR*); @@ -381,6 +382,8 @@ GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient*,GpRect*); GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient*,GpWrapMode*); GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient*,GDIPCONST REAL*, GDIPCONST REAL*,INT); +GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient*,REAL*,REAL*,INT); +GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient*,INT*); GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient*,ARGB,ARGB); GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient*,BOOL); GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient*,REAL,REAL); diff --git a/include/ipifcons.h b/include/ipifcons.h index b249b24ebd9..fe99b2ffff0 100644 --- a/include/ipifcons.h +++ b/include/ipifcons.h @@ -18,6 +18,35 @@ #ifndef WINE_IPIFCONS_H__ #define WINE_IPIFCONS_H__ +#define IF_TYPE_OTHER 1 +#define IF_TYPE_REGULAR_1822 2 +#define IF_TYPE_HDH_1822 3 +#define IF_TYPE_DDN_X25 4 +#define IF_TYPE_RFC877_X25 5 +#define IF_TYPE_ETHERNET_CSMACD 6 +#define IF_TYPE_IS088023_CSMACD 7 +#define IF_TYPE_ISO88024_TOKENBUS 8 +#define IF_TYPE_ISO88025_TOKENRING 9 +#define IF_TYPE_ISO88026_MAN 10 +#define IF_TYPE_STARLAN 11 +#define IF_TYPE_PROTEON_10MBIT 12 +#define IF_TYPE_PROTEON_80MBIT 13 +#define IF_TYPE_HYPERCHANNEL 14 +#define IF_TYPE_FDDI 15 +#define IF_TYPE_LAP_B 16 +#define IF_TYPE_SDLC 17 +#define IF_TYPE_DS1 18 +#define IF_TYPE_E1 19 +#define IF_TYPE_BASIC_ISDN 20 +#define IF_TYPE_PRIMARY_ISDN 21 +#define IF_TYPE_PROP_POINT2POINT_SERIAL 22 +#define IF_TYPE_PPP 23 +#define IF_TYPE_SOFTWARE_LOOPBACK 24 +#define IF_TYPE_EON 25 +#define IF_TYPE_ETHERNET_3MBIT 26 +#define IF_TYPE_NSIP 27 +#define IF_TYPE_SLIP 28 + #define MIB_IF_TYPE_OTHER 1 #define MIB_IF_TYPE_ETHERNET 6 #define MIB_IF_TYPE_TOKENRING 9 diff --git a/include/iptypes.h b/include/iptypes.h index c0b81153508..37a4b9ee38d 100644 --- a/include/iptypes.h +++ b/include/iptypes.h @@ -84,4 +84,139 @@ typedef struct { UINT EnableDns; } FIXED_INFO, *PFIXED_INFO; +typedef enum { + IpPrefixOriginOther = 0, + IpPrefixOriginManual, + IpPrefixOriginWellKnown, + IpPrefixOriginDhcp, + IpPrefixOriginRouterAdvertisement, + IpPrefixOriginUnchanged = 16 +} IP_PREFIX_ORIGIN; + +typedef enum { + IpSuffixOriginOther = 0, + IpSuffixOriginManual, + IpSuffixOriginWellKnown, + IpSuffixOriginDhcp, + IpSuffixOriginLinkLayerAddress, + IpSuffixOriginRandom, + IpSuffixOriginUnchanged = 16 +} IP_SUFFIX_ORIGIN; + +typedef enum { + IfOperStatusUp = 1, + IfOperStatusDown, + IfOperStatusTesting, + IfOperStatusUnknown, + IfOperStatusDormant, + IfOperStatusNotPresent, + IfOperStatusLowerLayerDown +} IF_OPER_STATUS; + +typedef enum { + IpDadStateInvalid = 0, + IpDadStateTentative, + IpDadStateDuplicate, + IpDadStateDeprecated, + IpDadStatePreferred +} IP_DAD_STATE; + +#ifdef _WINSOCK2API_ + +typedef struct _IP_ADAPTER_UNICAST_ADDRESS { + union { + struct { + ULONG Length; + DWORD Flags; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_UNICAST_ADDRESS *Next; + SOCKET_ADDRESS Address; + IP_PREFIX_ORIGIN PrefixOrigin; + IP_SUFFIX_ORIGIN SuffixOrigin; + IP_DAD_STATE DadState; + ULONG ValidLifetime; + ULONG PreferredLifetime; + ULONG LeaseLifetime; +} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS; + +typedef struct _IP_ADAPTER_ANYCAST_ADDRESS { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD Flags; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_ANYCAST_ADDRESS *Next; + SOCKET_ADDRESS Address; +} IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS; + +typedef struct _IP_ADAPTER_MULTICAST_ADDRESS { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD Flags; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_MULTICAST_ADDRESS *Next; + SOCKET_ADDRESS Address; +} IP_ADAPTER_MULTICAST_ADDRESS, *PIP_ADAPTER_MULTICAST_ADDRESS; + +typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD Reserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_DNS_SERVER_ADDRESS *Next; + SOCKET_ADDRESS Address; +} IP_ADAPTER_DNS_SERVER_ADDRESS, *PIP_ADAPTER_DNS_SERVER_ADDRESS; + +typedef struct _IP_ADAPTER_PREFIX { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD Flags; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_PREFIX *Next; + SOCKET_ADDRESS Address; + ULONG PrefixLength; +} IP_ADAPTER_PREFIX, *PIP_ADAPTER_PREFIX; + +typedef struct _IP_ADAPTER_ADDRESSES { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD IfIndex; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + struct _IP_ADAPTER_ADDRESSES *Next; + PCHAR AdapterName; + PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; + PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; + PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; + PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; + PWCHAR DnsSuffix; + PWCHAR Description; + PWCHAR FriendlyName; + BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; + DWORD PhysicalAddressLength; + DWORD Flags; + DWORD Mtu; + DWORD IfType; + IF_OPER_STATUS OperStatus; + DWORD Ipv6IfIndex; + DWORD ZoneIndices[16]; + PIP_ADAPTER_PREFIX FirstPrefix; +} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES; + +#endif /* _WINSOCK2API_ */ + #endif /* WINE_IPTYPES_H_*/ diff --git a/include/mshtmdid.h b/include/mshtmdid.h index 75a72906bf1..8f882f8c13c 100644 --- a/include/mshtmdid.h +++ b/include/mshtmdid.h @@ -1499,6 +1499,32 @@ #define DISPID_IHTMLBOOKMARKCOLLECTION__NEWENUM DISPID_NEWENUM #define DISPID_IHTMLBOOKMARKCOLLECTION_ITEM DISPID_VALUE +/* HTMLWindowEvents */ +#define DISPID_HTMLWINDOWEVENTS_ONLOAD DISPID_EVMETH_ONLOAD +#define DISPID_HTMLWINDOWEVENTS_ONUNLOAD DISPID_EVMETH_ONUNLOAD +#define DISPID_HTMLWINDOWEVENTS_ONHELP DISPID_EVMETH_ONHELP +#define DISPID_HTMLWINDOWEVENTS_ONFOCUS DISPID_EVMETH_ONFOCUS +#define DISPID_HTMLWINDOWEVENTS_ONBLUR DISPID_EVMETH_ONBLUR +#define DISPID_HTMLWINDOWEVENTS_ONERROR DISPID_EVMETH_ONERROR +#define DISPID_HTMLWINDOWEVENTS_ONRESIZE DISPID_EVMETH_ONRESIZE +#define DISPID_HTMLWINDOWEVENTS_ONSCROLL DISPID_EVMETH_ONSCROLL +#define DISPID_HTMLWINDOWEVENTS_ONBEFOREUNLOAD DISPID_EVMETH_ONBEFOREUNLOAD +#define DISPID_HTMLWINDOWEVENTS_ONBEFOREPRINT DISPID_EVMETH_ONBEFOREPRINT +#define DISPID_HTMLWINDOWEVENTS_ONAFTERPRINT DISPID_EVMETH_ONAFTERPRINT + +/* HTMLWindowEvents2 */ +#define DISPID_HTMLWINDOWEVENTS2_ONLOAD DISPID_EVMETH_ONLOAD +#define DISPID_HTMLWINDOWEVENTS2_ONUNLOAD DISPID_EVMETH_ONUNLOAD +#define DISPID_HTMLWINDOWEVENTS2_ONHELP DISPID_EVMETH_ONHELP +#define DISPID_HTMLWINDOWEVENTS2_ONFOCUS DISPID_EVMETH_ONFOCUS +#define DISPID_HTMLWINDOWEVENTS2_ONBLUR DISPID_EVMETH_ONBLUR +#define DISPID_HTMLWINDOWEVENTS2_ONERROR DISPID_EVMETH_ONERROR +#define DISPID_HTMLWINDOWEVENTS2_ONRESIZE DISPID_EVMETH_ONRESIZE +#define DISPID_HTMLWINDOWEVENTS2_ONSCROLL DISPID_EVMETH_ONSCROLL +#define DISPID_HTMLWINDOWEVENTS2_ONBEFOREUNLOAD DISPID_EVMETH_ONBEFOREUNLOAD +#define DISPID_HTMLWINDOWEVENTS2_ONBEFOREPRINT DISPID_EVMETH_ONBEFOREPRINT +#define DISPID_HTMLWINDOWEVENTS2_ONAFTERPRINT DISPID_EVMETH_ONAFTERPRINT + /* IHTMLWindow2 */ #define DISPID_IHTMLWINDOW2_HISTORY 2 #define DISPID_IHTMLWINDOW2_CLOSE 3 @@ -1572,6 +1598,9 @@ #define DISPID_IHTMLWINDOW4_CREATEPOPUP 1180 #define DISPID_IHTMLWINDOW4_FRAMEELEMENT 1181 +/* IHTMLWindow5 */ +#define DISPID_IHTMLWINDOW5_XMLHTTPREQUEST 1190 + /* IHTMLImageElementFactory */ #define DISPID_IHTMLIMAGEELEMENTFACTORY_CREATE DISPID_VALUE diff --git a/include/mshtml.idl b/include/mshtml.idl index 87c36079b60..c8537fcedac 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -13884,6 +13884,43 @@ interface IHTMLWindow3 : IDispatch } /***************************************************************************** + * IHTMLWindow4 interface + */ +[ + odl, + oleautomation, + dual, + uuid(3050f6cf-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLWindow4 : IDispatch +{ + [id(DISPID_IHTMLWINDOW4_CREATEPOPUP)] + HRESULT createPopup([optional, in] VARIANT* varArgIn, + [retval, out] IDispatch** ppPopup); + + [propget, id(DISPID_IHTMLWINDOW4_FRAMEELEMENT)] + HRESULT frameElement([retval, out] IHTMLFrameBase* * p); +}; + +/***************************************************************************** + * IHTMLWindow5 interface + */ +[ + odl, + oleautomation, + dual, + uuid(3051040e-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLWindow5 : IDispatch +{ + [propput, id(DISPID_IHTMLWINDOW5_XMLHTTPREQUEST)] + HRESULT XMLHttpRequest([in] VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW5_XMLHTTPREQUEST)] + HRESULT XMLHttpRequest([retval, out] VARIANT * p); +}; + +/***************************************************************************** * DispHTMLWindow2 dispinterface */ [ @@ -14169,6 +14206,408 @@ methods: } /***************************************************************************** + * DispHTMLWindowProxy dispinterface + */ +[ + hidden, + uuid(3050f55e-98b5-11cf-bb82-00aa00bdce0b) +] +dispinterface DispHTMLWindowProxy +{ +properties: +methods: + [id(DISPID_IHTMLFRAMESCOLLECTION2_ITEM)] + VARIANT item([in] VARIANT* pvarIndex); + + [propget, id(DISPID_IHTMLFRAMESCOLLECTION2_LENGTH)] + LONG length(); + + [propget, id(DISPID_IHTMLWINDOW2_FRAMES)] + IHTMLFramesCollection2* frames(); + + [propput, id(DISPID_IHTMLWINDOW2_DEFAULTSTATUS)] + void defaultStatus(BSTR v); + + [propget, id(DISPID_IHTMLWINDOW2_DEFAULTSTATUS)] + BSTR defaultStatus(); + + [propput, id(DISPID_IHTMLWINDOW2_STATUS)] + void status(BSTR v); + + [propget, id(DISPID_IHTMLWINDOW2_STATUS)] + BSTR status(); + + [id(DISPID_IHTMLWINDOW2_CLEARTIMEOUT)] + void clearTimeout([in] LONG timerID); + + [id(DISPID_IHTMLWINDOW2_ALERT)] + void alert([defaultvalue(""), in] BSTR message); + + [id(DISPID_IHTMLWINDOW2_CONFIRM)] + VARIANT_BOOL confirm([defaultvalue(""), in] BSTR message); + + [id(DISPID_IHTMLWINDOW2_PROMPT)] + VARIANT prompt([defaultvalue(""), in] BSTR message, + [defaultvalue("undefined"), in] BSTR defstr); + + [propget, id(DISPID_IHTMLWINDOW2_IMAGE)] + IHTMLImageElementFactory* Image(); + + [propget, id(DISPID_IHTMLWINDOW2_LOCATION)] + IHTMLLocation* location(); + + [propget, id(DISPID_IHTMLWINDOW2_HISTORY)] + IOmHistory* history(); + + [id(DISPID_IHTMLWINDOW2_CLOSE)] + void close(); + + [propput, id(DISPID_IHTMLWINDOW2_OPENER)] + void opener(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_OPENER)] + VARIANT opener(); + + [propget, id(DISPID_IHTMLWINDOW2_NAVIGATOR)] + IOmNavigator* navigator(); + + [propput, id(DISPID_IHTMLWINDOW2_NAME)] + void name(BSTR v); + + [propget, id(DISPID_IHTMLWINDOW2_NAME)] + BSTR name(); + + [propget, id(DISPID_IHTMLWINDOW2_PARENT)] + IHTMLWindow2* parent(); + + [id(DISPID_IHTMLWINDOW2_OPEN)] + IHTMLWindow2* open([defaultvalue(""), in] BSTR url, + [defaultvalue(""), in] BSTR name, + [defaultvalue(""), in] BSTR features, + [defaultvalue(0), in] VARIANT_BOOL replace); + + [propget, id(DISPID_IHTMLWINDOW2_SELF)] + IHTMLWindow2* self(); + + [propget, id(DISPID_IHTMLWINDOW2_TOP)] + IHTMLWindow2* top(); + + [propget, id(DISPID_IHTMLWINDOW2_WINDOW)] + IHTMLWindow2* window(); + + [id(DISPID_IHTMLWINDOW2_NAVIGATE)] + void navigate([in] BSTR url); + + [propput, id(DISPID_IHTMLWINDOW2_ONFOCUS), displaybind, bindable] + void onfocus(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONFOCUS), displaybind, bindable] + VARIANT onfocus(); + + [propput, id(DISPID_IHTMLWINDOW2_ONBLUR), displaybind, bindable] + void onblur(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONBLUR), displaybind, bindable] + VARIANT onblur(); + + [propput, id(DISPID_IHTMLWINDOW2_ONLOAD), displaybind, bindable] + void onload(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONLOAD), displaybind, bindable] + VARIANT onload(); + + [propput, id(DISPID_IHTMLWINDOW2_ONBEFOREUNLOAD), displaybind, bindable] + void onbeforeunload(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONBEFOREUNLOAD), displaybind, bindable] + VARIANT onbeforeunload(); + + [propput, id(DISPID_IHTMLWINDOW2_ONUNLOAD), displaybind, bindable] + void onunload(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONUNLOAD), displaybind, bindable] + VARIANT onunload(); + + [propput, id(DISPID_IHTMLWINDOW2_ONHELP), displaybind, bindable] + void onhelp(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONHELP), displaybind, bindable] + VARIANT onhelp(); + + [propput, id(DISPID_IHTMLWINDOW2_ONERROR), displaybind, bindable] + void onerror(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONERROR), displaybind, bindable] + VARIANT onerror(); + + [propput, id(DISPID_IHTMLWINDOW2_ONRESIZE), displaybind, bindable] + void onresize(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONRESIZE), displaybind, bindable] + VARIANT onresize(); + + [propput, id(DISPID_IHTMLWINDOW2_ONSCROLL), displaybind, bindable] + void onscroll(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_ONSCROLL), displaybind, bindable] + VARIANT onscroll(); + + [propget, id(DISPID_IHTMLWINDOW2_DOCUMENT), source] + IHTMLDocument2* document(); + + [propget, id(DISPID_IHTMLWINDOW2_EVENT)] + IHTMLEventObj* event(); + + [propget, id(DISPID_IHTMLWINDOW2__NEWENUM), hidden, restricted] + IUnknown* _newEnum(); + + [id(DISPID_IHTMLWINDOW2_SHOWMODALDIALOG)] + VARIANT showModalDialog([in] BSTR dialog, + [optional, in] VARIANT* varArgIn, + [optional, in] VARIANT* varOptions); + + [id(DISPID_IHTMLWINDOW2_SHOWHELP)] + void showHelp([in] BSTR helpURL, + [optional, in] VARIANT helpArg, + [defaultvalue(""), in] BSTR features); + + [propget, id(DISPID_IHTMLWINDOW2_SCREEN)] + IHTMLScreen* screen(); + + [propget, id(DISPID_IHTMLWINDOW2_OPTION)] + IHTMLOptionElementFactory* Option(); + + [id(DISPID_IHTMLWINDOW2_FOCUS)] + void focus(); + + [propget, id(DISPID_IHTMLWINDOW2_CLOSED)] + VARIANT_BOOL closed(); + + [id(DISPID_IHTMLWINDOW2_BLUR)] + void blur(); + + [id(DISPID_IHTMLWINDOW2_SCROLL)] + void scroll([in] LONG x, + [in] LONG y); + + [propget, id(DISPID_IHTMLWINDOW2_CLIENTINFORMATION)] + IOmNavigator* clientInformation(); + + [id(DISPID_IHTMLWINDOW2_CLEARINTERVAL)] + void clearInterval([in] LONG timerID); + + [propput, id(DISPID_IHTMLWINDOW2_OFFSCREENBUFFERING)] + void offscreenBuffering(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW2_OFFSCREENBUFFERING)] + VARIANT offscreenBuffering(); + + [id(DISPID_IHTMLWINDOW2_EXECSCRIPT)] + VARIANT execScript([in] BSTR code, + [defaultvalue("JScript"), in] BSTR language); + + [id(DISPID_IHTMLWINDOW2_TOSTRING)] + BSTR toString(); + + [id(DISPID_IHTMLWINDOW2_SCROLLBY)] + void scrollBy([in] LONG x, + [in] LONG y); + + [id(DISPID_IHTMLWINDOW2_SCROLLTO)] + void scrollTo([in] LONG x, + [in] LONG y); + + [id(DISPID_IHTMLWINDOW2_MOVETO)] + void moveTo([in] LONG x, + [in] LONG y); + + [id(DISPID_IHTMLWINDOW2_MOVEBY)] + void moveBy([in] LONG x, + [in] LONG y); + + [id(DISPID_IHTMLWINDOW2_RESIZETO)] + void resizeTo([in] LONG x, + [in] LONG y); + + [id(DISPID_IHTMLWINDOW2_RESIZEBY)] + void resizeBy([in] LONG x, + [in] LONG y); + + [propget, id(DISPID_IHTMLWINDOW2_EXTERNAL)] + IDispatch* external(); + + [propget, id(DISPID_IHTMLWINDOW3_SCREENLEFT)] + LONG screenLeft(); + + [propget, id(DISPID_IHTMLWINDOW3_SCREENTOP)] + LONG screenTop(); + + [id(DISPID_IHTMLWINDOW3_ATTACHEVENT)] + VARIANT_BOOL attachEvent([in] BSTR event, + [in] IDispatch* pDisp); + + [id(DISPID_IHTMLWINDOW3_DETACHEVENT)] + void detachEvent([in] BSTR event, + [in] IDispatch* pDisp); + + [id(DISPID_IHTMLWINDOW3_SETTIMEOUT)] + LONG setTimeout([in] VARIANT* expression, + [in] LONG msec, + [optional, in] VARIANT* language); + + [id(DISPID_IHTMLWINDOW3_SETINTERVAL)] + LONG setInterval([in] VARIANT* expression, + [in] LONG msec, + [optional, in] VARIANT* language); + + [id(DISPID_IHTMLWINDOW3_PRINT)] + void print(); + + [propput, id(DISPID_IHTMLWINDOW3_ONBEFOREPRINT), displaybind, bindable] + void onbeforeprint(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW3_ONBEFOREPRINT), displaybind, bindable] + VARIANT onbeforeprint(); + + [propput, id(DISPID_IHTMLWINDOW3_ONAFTERPRINT), displaybind, bindable] + void onafterprint(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW3_ONAFTERPRINT), displaybind, bindable] + VARIANT onafterprint(); + + [propget, id(DISPID_IHTMLWINDOW3_CLIPBOARDDATA)] + IHTMLDataTransfer* clipboardData(); + + [id(DISPID_IHTMLWINDOW3_SHOWMODELESSDIALOG)] + IHTMLWindow2* showModelessDialog([defaultvalue(""), in] BSTR url, + [optional, in] VARIANT* varArgIn, + [optional, in] VARIANT* options); + + [id(DISPID_IHTMLWINDOW4_CREATEPOPUP)] + IDispatch* createPopup([optional, in] VARIANT* varArgIn); + + [propget, id(DISPID_IHTMLWINDOW4_FRAMEELEMENT)] + IHTMLFrameBase* frameElement(); + + [propput, id(DISPID_IHTMLWINDOW5_XMLHTTPREQUEST)] + void XMLHttpRequest(VARIANT v); + + [propget, id(DISPID_IHTMLWINDOW5_XMLHTTPREQUEST)] + VARIANT XMLHttpRequest(); +}; + +/***************************************************************************** + * HTMLWindowEvents interface + */ +[ + hidden, + uuid(96A0A4E0-D062-11cf-94B6-00AA0060275C) +] +dispinterface HTMLWindowEvents +{ +properties: +methods: + [id(DISPID_HTMLWINDOWEVENTS_ONLOAD)] + void onload(); + + [id(DISPID_HTMLWINDOWEVENTS_ONUNLOAD)] + void onunload(); + + [id(DISPID_HTMLWINDOWEVENTS_ONHELP)] + VARIANT_BOOL onhelp(); + + [id(DISPID_HTMLWINDOWEVENTS_ONFOCUS)] + void onfocus(); + + [id(DISPID_HTMLWINDOWEVENTS_ONBLUR)] + void onblur(); + + [id(DISPID_HTMLWINDOWEVENTS_ONERROR)] + void onerror([in] BSTR description, + [in] BSTR url, + [in] LONG line); + + [id(DISPID_HTMLWINDOWEVENTS_ONRESIZE)] + void onresize(); + + [id(DISPID_HTMLWINDOWEVENTS_ONSCROLL)] + void onscroll(); + + [id(DISPID_HTMLWINDOWEVENTS_ONBEFOREUNLOAD)] + void onbeforeunload(); + + [id(DISPID_HTMLWINDOWEVENTS_ONBEFOREPRINT)] + void onbeforeprint(); + + [id(DISPID_HTMLWINDOWEVENTS_ONAFTERPRINT)] + void onafterprint(); +}; + +/***************************************************************************** + * HTMLWindowEvents2 interface + */ +[ + hidden, + uuid(3050f625-98b5-11cf-bb82-00aa00bdce0b) +] +dispinterface HTMLWindowEvents2 +{ +properties: +methods: + [id(DISPID_HTMLWINDOWEVENTS2_ONLOAD)] + void onload([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONUNLOAD)] + void onunload([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONHELP)] + VARIANT_BOOL onhelp([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONFOCUS)] + void onfocus([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONBLUR)] + void onblur([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONERROR)] + void onerror([in] BSTR description, + [in] BSTR url, + [in] LONG line); + + [id(DISPID_HTMLWINDOWEVENTS2_ONRESIZE)] + void onresize([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONSCROLL)] + void onscroll([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONBEFOREUNLOAD)] + void onbeforeunload([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONBEFOREPRINT)] + void onbeforeprint([in] IHTMLEventObj* pEvtObj); + + [id(DISPID_HTMLWINDOWEVENTS2_ONAFTERPRINT)] + void onafterprint([in] IHTMLEventObj* pEvtObj); +}; + +/***************************************************************************** + * HTMLWindowProxy class + */ +[ + uuid(3050f391-98b5-11cf-bb82-00aa00bdce0b) +] +coclass HTMLWindowProxy +{ + [default] dispinterface DispHTMLWindowProxy; + [source, default] dispinterface HTMLWindowEvents; + [source] dispinterface HTMLWindowEvents2; + interface IHTMLWindow2; + interface IHTMLWindow3; + interface IHTMLWindow4; + interface IHTMLWindow5; +}; + +/***************************************************************************** * HTMLDocumentEvents2 interface */ [ diff --git a/include/shlobj.h b/include/shlobj.h index b7efc852c0c..df3a9595a75 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -64,6 +64,7 @@ BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST,LPWSTR); INT WINAPI SHHandleUpdateImage(LPCITEMIDLIST); HRESULT WINAPI SHILCreateFromPath(LPCWSTR,LPITEMIDLIST*,DWORD*); HRESULT WINAPI SHLoadOLE(LPARAM); +HRESULT WINAPI SHParseDisplayName(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*); HRESULT WINAPI SHPathPrepareForWriteA(HWND,IUnknown*,LPCSTR,DWORD); HRESULT WINAPI SHPathPrepareForWriteW(HWND,IUnknown*,LPCWSTR,DWORD); #define SHPathPrepareForWrite WINELIB_NAME_AW(SHPathPrepareForWrite); diff --git a/include/wininet.h b/include/wininet.h index d3263fef279..6ce8ae03868 100644 --- a/include/wininet.h +++ b/include/wininet.h @@ -1356,6 +1356,23 @@ INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingA(HWND ,LPSTR ,LPSTR ,BOOL); INTERNETAPI DWORD WINAPI InternetConfirmZoneCrossingW(HWND ,LPWSTR ,LPWSTR ,BOOL); #define InternetConfirmZoneCrossing WINELIB_NAME_AW(InternetConfirmZoneCrossing) +#define PRIVACY_TEMPLATE_NO_COOKIES 0 +#define PRIVACY_TEMPLATE_HIGH 1 +#define PRIVACY_TEMPLATE_MEDIUM_HIGH 2 +#define PRIVACY_TEMPLATE_MEDIUM 3 +#define PRIVACY_TEMPLATE_MEDIUM_LOW 4 +#define PRIVACY_TEMPLATE_LOW 5 +#define PRIVACY_TEMPLATE_CUSTOM 100 +#define PRIVACY_TEMPLATE_ADVANCED 101 + +#define PRIVACY_TEMPLATE_MAX PRIVACY_TEMPLATE_LOW + +#define PRIVACY_TYPE_FIRST_PARTY 0 +#define PRIVACY_TYPE_THIRD_PARTY 1 + +INTERNETAPI DWORD WINAPI PrivacySetZonePreferenceW(DWORD,DWORD,DWORD,LPCWSTR); +INTERNETAPI DWORD WINAPI PrivacyGetZonePreferenceW(DWORD,DWORD,LPDWORD,LPWSTR,LPDWORD); + #define INTERNET_ERROR_BASE 12000 #define ERROR_INTERNET_OUT_OF_HANDLES (INTERNET_ERROR_BASE + 1) diff --git a/include/ws2ipdef.h b/include/ws2ipdef.h index ff2b2019c63..bc30f96ecee 100644 --- a/include/ws2ipdef.h +++ b/include/ws2ipdef.h @@ -247,9 +247,25 @@ struct WS(ip_msfilter) { #ifndef USE_WS_PREFIX #define INET_ADDRSTRLEN 22 #define INET6_ADDRSTRLEN 65 +#define IN6ADDR_ANY_INIT { 0 } +#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } #else #define WS_INET_ADDRSTRLEN 22 #define WS_INET6_ADDRSTRLEN 65 +#define WS_IN6ADDR_ANY_INIT { 0 } +#define WS_IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } #endif /* USE_WS_PREFIX */ +static inline BOOL WS(IN6_IS_ADDR_LOOPBACK) ( const IN6_ADDR *a ) +{ + return (BOOL)((a->s6_words[0] == 0) && + (a->s6_words[1] == 0) && + (a->s6_words[2] == 0) && + (a->s6_words[3] == 0) && + (a->s6_words[4] == 0) && + (a->s6_words[5] == 0) && + (a->s6_words[6] == 0) && + (a->s6_words[7] == 0x0100)); +} + #endif /* __WS2IPDEF__ */ diff --git a/include/ws2tcpip.h b/include/ws2tcpip.h index 6f1293f7c27..0461a8125bf 100644 --- a/include/ws2tcpip.h +++ b/include/ws2tcpip.h @@ -161,9 +161,9 @@ int WINAPI WS(getnameinfo)(const SOCKADDR*,WS(socklen_t),PCHAR,DWORD,PCHAR,DWOR #define GetNameInfoA WS(getnameinfo) INT WINAPI GetNameInfoW(const SOCKADDR*,WS(socklen_t),PWCHAR,DWORD,PWCHAR,DWORD,INT); #define GetNameInfo WINELIB_NAME_AW(GetNameInfo) -PCSTR WINAPI WS(inet_ntop)(INT,PVOID,PSTR,size_t); +PCSTR WINAPI WS(inet_ntop)(INT,PVOID,PSTR,SIZE_T); #define InetNtopA WS(inet_ntop) -PCWSTR WINAPI InetNtopW(INT,PVOID,PWSTR,size_t); +PCWSTR WINAPI InetNtopW(INT,PVOID,PWSTR,SIZE_T); #define InetNtop WINELIB_NAME_AW(InetNtop) int WINAPI WS(inet_pton)(INT,PCSTR,PVOID); #define InetPtonA WS(inet_pton) diff --git a/programs/cmdlgtst/De.rc b/programs/cmdlgtst/De.rc index 323b6f8d8bd..f8e7d0e31e5 100644 --- a/programs/cmdlgtst/De.rc +++ b/programs/cmdlgtst/De.rc @@ -145,7 +145,7 @@ FONT 8, "MS Shell Dlg" CONTROL "", -1, "static", SS_BLACKRECT | WS_CHILD | WS_VISIBLE, 12, 168, 11, 13 CONTROL "", -1, "static", SS_BLACKRECT | WS_CHILD | WS_VISIBLE, 12, 180, 11, 13 CONTROL "", -1, "static", SS_BLACKRECT | WS_CHILD | WS_VISIBLE, 24, 228, 11, 13 - CONTROL "Markierte Flags sind durch das System gesetzt wurden und müssen von dem Benutzer entfernt werden", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 48, 228, 98, 36 + CONTROL "Markierte Flags sind durch das System gesetzt worden und müssen von dem Benutzer entfernt werden", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 48, 228, 98, 36 } Print_Flags_Dialog DIALOG 4, 17, 239, 287 diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 480d2450c54..67ade26e223 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -326,6 +326,9 @@ void manage_desktop( WCHAR *arg ) if (hwnd == GetDesktopWindow()) { + HMODULE shell32; + void (WINAPI *pShellDDEInit)( BOOL ); + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)desktop_wnd_proc ); SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO))); if (name) set_desktop_window_title( hwnd, name ); @@ -334,6 +337,12 @@ void manage_desktop( WCHAR *arg ) initialize_display_settings( hwnd ); initialize_appbar(); initialize_systray(); + + if ((shell32 = LoadLibraryA( "shell32.dll" )) && + (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188))) + { + pShellDDEInit( TRUE ); + } } else { diff --git a/programs/notepad/De.rc b/programs/notepad/De.rc index 24d713a52a8..fb315a863fb 100644 --- a/programs/notepad/De.rc +++ b/programs/notepad/De.rc @@ -53,6 +53,7 @@ POPUP "&Bearbeiten" { POPUP "&Suchen" { MENUITEM "Suchen...\tStrg+F", CMD_SEARCH MENUITEM "&Weitersuchen\tF3", CMD_SEARCH_NEXT + MENUITEM "&Ersetzen...\tStrg+H", CMD_REPLACE } POPUP "&Hilfe" { MENUITEM "&Inhalt", CMD_HELP_CONTENTS diff --git a/programs/notepad/En.rc b/programs/notepad/En.rc index c68404e35c5..c4a4baf440e 100644 --- a/programs/notepad/En.rc +++ b/programs/notepad/En.rc @@ -53,6 +53,7 @@ POPUP "&Edit" { POPUP "&Search" { MENUITEM "&Search...\tCtrl+F", CMD_SEARCH MENUITEM "&Search next\tF3", CMD_SEARCH_NEXT + MENUITEM "&Replace...\tCtrl+H", CMD_REPLACE } POPUP "&Help" { MENUITEM "&Contents", CMD_HELP_CONTENTS diff --git a/programs/notepad/dialog.c b/programs/notepad/dialog.c index 0595f690d2d..0abbc33bec1 100644 --- a/programs/notepad/dialog.c +++ b/programs/notepad/dialog.c @@ -654,12 +654,12 @@ VOID DIALOG_EditTimeDate(VOID) GetLocalTime(&st); - GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN); + GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, szDate, MAX_STRING_LEN); SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate); SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)spaceW); - GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN); + GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN); SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate); } @@ -724,6 +724,13 @@ VOID DIALOG_SelectFont(VOID) VOID DIALOG_Search(VOID) { + /* Allow only one search/replace dialog to open */ + if(Globals.hFindReplaceDlg != NULL) + { + SetActiveWindow(Globals.hFindReplaceDlg); + return; + } + ZeroMemory(&Globals.find, sizeof(Globals.find)); Globals.find.lStructSize = sizeof(Globals.find); Globals.find.hwndOwner = Globals.hMainWnd; @@ -747,6 +754,32 @@ VOID DIALOG_SearchNext(VOID) NOTEPAD_DoFind(&Globals.lastFind); } +VOID DIALOG_Replace(VOID) +{ + /* Allow only one search/replace dialog to open */ + if(Globals.hFindReplaceDlg != NULL) + { + SetActiveWindow(Globals.hFindReplaceDlg); + return; + } + + ZeroMemory(&Globals.find, sizeof(Globals.find)); + Globals.find.lStructSize = sizeof(Globals.find); + Globals.find.hwndOwner = Globals.hMainWnd; + Globals.find.hInstance = Globals.hInstance; + Globals.find.lpstrFindWhat = Globals.szFindText; + Globals.find.wFindWhatLen = SIZEOF(Globals.szFindText); + Globals.find.lpstrReplaceWith = Globals.szReplaceText; + Globals.find.wReplaceWithLen = SIZEOF(Globals.szReplaceText); + Globals.find.Flags = FR_DOWN|FR_HIDEWHOLEWORD; + + /* We only need to create the modal FindReplace dialog which will */ + /* notify us of incoming events using hMainWnd Window Messages */ + + Globals.hFindReplaceDlg = ReplaceText(&Globals.find); + assert(Globals.hFindReplaceDlg !=0); +} + VOID DIALOG_HelpContents(VOID) { WinHelp(Globals.hMainWnd, helpfileW, HELP_INDEX, 0); diff --git a/programs/notepad/dialog.h b/programs/notepad/dialog.h index d7809915aec..d9271431444 100644 --- a/programs/notepad/dialog.h +++ b/programs/notepad/dialog.h @@ -38,6 +38,7 @@ VOID DIALOG_EditWrap(VOID); VOID DIALOG_Search(VOID); VOID DIALOG_SearchNext(VOID); +VOID DIALOG_Replace(VOID); VOID DIALOG_SelectFont(VOID); diff --git a/programs/notepad/main.c b/programs/notepad/main.c index 1751c90f509..33b48595e1a 100644 --- a/programs/notepad/main.c +++ b/programs/notepad/main.c @@ -294,6 +294,7 @@ static int NOTEPAD_MenuCommand(WPARAM wParam) case CMD_SEARCH: DIALOG_Search(); break; case CMD_SEARCH_NEXT: DIALOG_SearchNext(); break; + case CMD_REPLACE: DIALOG_Replace(); break; case CMD_WRAP: DIALOG_EditWrap(); break; case CMD_FONT: DIALOG_SelectFont(); break; @@ -414,6 +415,77 @@ void NOTEPAD_DoFind(FINDREPLACE *fr) SendMessage(Globals.hEdit, EM_SETSEL, found - content, found - content + len); } +void NOTEPAD_DoReplace(FINDREPLACE *fr) +{ + LPTSTR content; + int len = lstrlen(fr->lpstrFindWhat); + int fileLen; + DWORD pos; + DWORD pos_start; + + fileLen = GetWindowTextLength(Globals.hEdit) + 1; + content = HeapAlloc(GetProcessHeap(), 0, fileLen * sizeof(TCHAR)); + if (!content) return; + GetWindowText(Globals.hEdit, content, fileLen); + + SendMessage(Globals.hEdit, EM_GETSEL, (WPARAM)&pos_start, (LPARAM)&pos); + switch (fr->Flags & (FR_DOWN|FR_MATCHCASE)) + { + case FR_DOWN: + if ( pos-pos_start == len && StrCmpNI(fr->lpstrFindWhat, content+pos_start, len) == 0) + SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)fr->lpstrReplaceWith); + break; + case FR_DOWN|FR_MATCHCASE: + if ( pos-pos_start == len && StrCmpN(fr->lpstrFindWhat, content+pos_start, len) == 0) + SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)fr->lpstrReplaceWith); + break; + default: /* shouldn't happen */ + return; + } + HeapFree(GetProcessHeap(), 0, content); + + NOTEPAD_DoFind(fr); +} + +void NOTEPAD_DoReplaceAll(FINDREPLACE *fr) +{ + LPTSTR content; + LPTSTR found; + int len = lstrlen(fr->lpstrFindWhat); + int fileLen; + DWORD pos; + + SendMessage(Globals.hEdit, EM_SETSEL, 0, 0); + while(TRUE){ + fileLen = GetWindowTextLength(Globals.hEdit) + 1; + content = HeapAlloc(GetProcessHeap(), 0, fileLen * sizeof(TCHAR)); + if (!content) return; + GetWindowText(Globals.hEdit, content, fileLen); + + SendMessage(Globals.hEdit, EM_GETSEL, 0, (LPARAM)&pos); + switch (fr->Flags & (FR_DOWN|FR_MATCHCASE)) + { + case FR_DOWN: + found = StrStrI(content+pos, fr->lpstrFindWhat); + break; + case FR_DOWN|FR_MATCHCASE: + found = StrStr(content+pos, fr->lpstrFindWhat); + break; + default: /* shouldn't happen */ + return; + } + HeapFree(GetProcessHeap(), 0, content); + + if(found == NULL) + { + SendMessage(Globals.hEdit, EM_SETSEL, 0, 0); + return; + } + SendMessage(Globals.hEdit, EM_SETSEL, found - content, found - content + len); + SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)fr->lpstrReplaceWith); + } +} + /*********************************************************************** * * NOTEPAD_WndProc @@ -432,6 +504,16 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, Globals.lastFind = *fr; NOTEPAD_DoFind(fr); } + if (fr->Flags & FR_REPLACE) + { + Globals.lastFind = *fr; + NOTEPAD_DoReplace(fr); + } + if (fr->Flags & FR_REPLACEALL) + { + Globals.lastFind = *fr; + NOTEPAD_DoReplaceAll(fr); + } return 0; } diff --git a/programs/notepad/main.h b/programs/notepad/main.h index 51db639dfda..88e7fbedea6 100644 --- a/programs/notepad/main.h +++ b/programs/notepad/main.h @@ -35,6 +35,7 @@ typedef struct LOGFONT lfFont; BOOL bWrapLongLines; WCHAR szFindText[MAX_PATH]; + WCHAR szReplaceText[MAX_PATH]; WCHAR szFileName[MAX_PATH]; WCHAR szFileTitle[MAX_PATH]; WCHAR szFilter[2 * MAX_STRING_LEN + 100]; diff --git a/programs/notepad/notepad_res.h b/programs/notepad/notepad_res.h index 9228a5ef43d..8176b855e7f 100644 --- a/programs/notepad/notepad_res.h +++ b/programs/notepad/notepad_res.h @@ -45,6 +45,7 @@ #define CMD_SEARCH 0x120 #define CMD_SEARCH_NEXT 0x121 +#define CMD_REPLACE 0x122 #define CMD_WRAP 0x119 #define CMD_FONT 0x140 diff --git a/programs/notepad/rsrc.rc b/programs/notepad/rsrc.rc index 8018a58a4d7..50b3558f5ad 100644 --- a/programs/notepad/rsrc.rc +++ b/programs/notepad/rsrc.rc @@ -30,6 +30,7 @@ ID_ACCEL ACCELERATORS "^A", CMD_SELECT_ALL "^C", CMD_COPY "^F", CMD_SEARCH + "H", CMD_REPLACE, VIRTKEY, CONTROL "^N", CMD_NEW "^O", CMD_OPEN "^P", CMD_PRINT diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 46756ce3a59..6327c9ae9fd 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -526,7 +526,7 @@ DWORD svcctl_ChangeServiceConfigW( WINE_FIXME("Changing tag id not supported\n"); if (lpDependencies != NULL) - WINE_FIXME("Chainging dependencies not supported\n"); + WINE_FIXME("Changing dependencies not supported\n"); if (lpServiceStartName != NULL) new_entry.config.lpServiceStartName = (LPWSTR)lpServiceStartName; diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 6cee70cbae1..7bbb0cbf7bc 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -912,6 +912,7 @@ int main( int argc, char *argv[] ) } break; case 'x': + report (R_TEXTMODE); if (!(extract = argv[++i])) extract = ".\\wct"; diff --git a/tools/winemaker b/tools/winemaker index eca64173c8d..5300e15918b 100755 --- a/tools/winemaker +++ b/tools/winemaker @@ -627,13 +627,20 @@ sub source_scan_project_file($$$) # Disables inline Expansion $prj_target_cflags.="-fno-inline "; } elsif (/^Ob1$/) { - # In-line Function Expansion + #In-line Function Expansion + $prj_target_cflags.="-finline-functions "; } elsif (/^Ob2$/) { # auto In-line Function Expansion $prj_target_cflags.="-finline-functions "; + } elsif (/^Ox$/) { + # Use maximum optimization + $prj_target_cflags.="-O3 "; } elsif (/^Oy$/) { # Frame-Pointer Omission $prj_target_cflags.="-fomit-frame-pointer "; + } elsif (/^Oy-$/) { + # Frame-Pointer Omission + $prj_target_cflags.="-fno-omit-frame-pointer "; } elsif (/^GZ$/) { # Catch Release-Build Errors in Debug Build } elsif (/^M[DLT]d?$/) { @@ -1096,10 +1103,11 @@ sub source_scan_workspace_file($) s/\r\n$/\n/; # catch a project definition - if (/^Project:\s\"(.*)\"=(.*)\s-/) { + if (/^Project:\s\"(.*)\"=\"?(.*)\s-/) { $prj_name=$1; $prj_path=$2; - @components=split /[\/\\]+/, $2; + $prj_path=~s/\"$//; + @components=split /[\/\\]+/, $prj_path; $prj_path=search_from($path, \@components); print "Name: $prj_name\nPath: $prj_path\n"; source_scan_project_file(\@main_project,1,$prj_path); @@ -1724,7 +1732,7 @@ sub search_from($$) my $path=$_[1]; my $real_path=""; - if ($dirname eq "" or $dirname eq ".") { + if ($dirname eq "" or $dirname eq "." or $dirname eq "./") { $dirname=cwd; } elsif ($dirname !~ m+^/+) { $dirname=cwd . "/" . $dirname; @@ -1734,6 +1742,8 @@ sub search_from($$) } foreach my $component (@$path) { + $component=~s/^\"//; + $component=~s/\"$//; #print " looking for $component in \"$dirname\"\n"; if ($component eq ".") { # Pass it as is -- 2.11.4.GIT