From: Aleksey Bragin Date: Wed, 21 Apr 2010 20:35:09 +0000 (+0000) Subject: [WINESYNC] X-Git-Tag: backups/header-work@57446~33^2~88 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=577625f6f8dcc2bb20a2e00a24b5ebd3a5a94dea [WINESYNC] - Sync comdlg32, crypt32, gdiplus, inetcomm, jscript, msctf, mshtml, msxml3, rsaenh, schannel, shlwapi, urlmon, usp10, wininet winetests. svn path=/trunk/; revision=46982 --- diff --git a/rostests/winetests/comdlg32/comdlg32.rbuild b/rostests/winetests/comdlg32/comdlg32.rbuild index d24dc1bd3c8..2d5dec28046 100644 --- a/rostests/winetests/comdlg32/comdlg32.rbuild +++ b/rostests/winetests/comdlg32/comdlg32.rbuild @@ -5,11 +5,13 @@ . filedlg.c + fontdlg.c printdlg.c testlist.c rsrc.rc wine comdlg32 + winspool user32 gdi32 ntdll diff --git a/rostests/winetests/comdlg32/filedlg.c b/rostests/winetests/comdlg32/filedlg.c index 9714dda1fe3..71f7d2a2595 100644 --- a/rostests/winetests/comdlg32/filedlg.c +++ b/rostests/winetests/comdlg32/filedlg.c @@ -29,6 +29,32 @@ /* ##### */ +static int resizesupported = TRUE; + +static void toolbarcheck( HWND hDlg) +{ + /* test toolbar properties */ + /* bug #10532 */ + int maxtextrows; + HWND ctrl; + DWORD ret; + char classname[20]; + + for( ctrl = GetWindow( hDlg, GW_CHILD); + ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) { + GetClassName( ctrl, classname, 10); + classname[7] = '\0'; + if( !strcmp( classname, "Toolbar")) break; + } + ok( ctrl != NULL, "could not get the toolbar control\n"); + ret = SendMessage( ctrl, TB_ADDSTRING, 0, (LPARAM)"winetestwinetest\0\0"); + ok( ret == 0, "addstring returned %d (expected 0)\n", ret); + maxtextrows = SendMessage( ctrl, TB_GETTEXTROWS, 0, 0); + ok( maxtextrows == 0 || broken(maxtextrows == 1), /* Win2k and below */ + "Get(Max)TextRows returned %d (expected 0)\n", maxtextrows); +} + + static UINT_PTR CALLBACK OFNHookProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR nmh; @@ -49,6 +75,7 @@ static UINT_PTR CALLBACK OFNHookProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM ok(ret > 0, "CMD_GETFOLDERIDLIST not implemented\n"); if (ret > 5) ok(buf[0] == 0x66 && buf[1] == 0x66, "CMD_GETFOLDERIDLIST: The buffer was touched on failure\n"); + toolbarcheck( GetParent(hDlg)); } } @@ -78,26 +105,26 @@ static void test_DialogCancel(void) ofn.lpstrInitialDir = szInitialDir; PrintDlgA(NULL); - ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n", - CDERR_INITIALIZATION, CommDlgExtendedError()); + ok(CDERR_INITIALIZATION == CommDlgExtendedError(), + "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError()); result = GetOpenFileNameA(&ofn); - ok(0 == result, "expected %d, got %d\n", 0, result); - ok(0 == CommDlgExtendedError(), "expected %d, got %d\n", 0, + ok(0 == result, "expected 0, got %d\n", result); + ok(0 == CommDlgExtendedError(), "expected 0, got %d\n", CommDlgExtendedError()); PrintDlgA(NULL); - ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n", - CDERR_INITIALIZATION, CommDlgExtendedError()); + ok(CDERR_INITIALIZATION == CommDlgExtendedError(), + "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError()); result = GetSaveFileNameA(&ofn); - ok(0 == result, "expected %d, got %d\n", 0, result); - ok(0 == CommDlgExtendedError(), "expected %d, got %d\n", 0, + ok(0 == result, "expected 0, got %d\n", result); + ok(0 == CommDlgExtendedError(), "expected 0, got %d\n", CommDlgExtendedError()); PrintDlgA(NULL); - ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n", - CDERR_INITIALIZATION, CommDlgExtendedError()); + ok(CDERR_INITIALIZATION == CommDlgExtendedError(), + "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError()); /* Before passing the ofn to Unicode functions, remove the ANSI strings */ ofn.lpstrFilter = NULL; @@ -105,8 +132,8 @@ static void test_DialogCancel(void) ofn.lpstrDefExt = NULL; PrintDlgA(NULL); - ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n", - CDERR_INITIALIZATION, CommDlgExtendedError()); + ok(CDERR_INITIALIZATION == CommDlgExtendedError(), + "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError()); SetLastError(0xdeadbeef); result = GetOpenFileNameW((LPOPENFILENAMEW) &ofn); @@ -114,11 +141,10 @@ static void test_DialogCancel(void) win_skip("GetOpenFileNameW is not implemented\n"); else { - ok(0 == result, "expected %d, got %d\n", 0, result); + ok(0 == result, "expected 0, got %d\n", result); ok(0 == CommDlgExtendedError() || - CDERR_INITIALIZATION == CommDlgExtendedError(), /* win9x */ - "expected %d or %d, got %d\n", 0, CDERR_INITIALIZATION, - CommDlgExtendedError()); + broken(CDERR_INITIALIZATION == CommDlgExtendedError()), /* win9x */ + "expected 0, got %d\n", CommDlgExtendedError()); } SetLastError(0xdeadbeef); @@ -127,11 +153,10 @@ static void test_DialogCancel(void) win_skip("GetSaveFileNameW is not implemented\n"); else { - ok(0 == result, "expected %d, got %d\n", 0, result); + ok(0 == result, "expected 0, got %d\n", result); ok(0 == CommDlgExtendedError() || - CDERR_INITIALIZATION == CommDlgExtendedError(), /* win9x */ - "expected %d or %d, got %d\n", 0, CDERR_INITIALIZATION, - CommDlgExtendedError()); + broken(CDERR_INITIALIZATION == CommDlgExtendedError()), /* win9x */ + "expected 0, got %d\n", CommDlgExtendedError()); } } @@ -177,12 +202,19 @@ static UINT_PTR CALLBACK create_view_window2_hook(HWND dlg, UINT msg, WPARAM wPa view_params.hwndView = NULL; hr = IShellView2_CreateViewWindow2(shell_view2, &view_params); + if (hr == E_FAIL) + { + win_skip("CreateViewWindow2 is broken on Vista/W2K8\n"); + goto cleanup; + } ok(SUCCEEDED(hr), "CreateViewWindow2 returned %#x\n", hr); if (FAILED(hr)) goto cleanup; hr = IShellView2_GetCurrentInfo(shell_view2, &folder_settings); ok(SUCCEEDED(hr), "GetCurrentInfo returned %#x\n", hr); - ok(folder_settings.ViewMode == FVM_LIST, "view mode is %d, expected %d\n", folder_settings.ViewMode, FVM_LIST); + ok(folder_settings.ViewMode == FVM_LIST, + "view mode is %d, expected FVM_LIST\n", + folder_settings.ViewMode); hr = IShellView2_DestroyViewWindow(shell_view2); ok(SUCCEEDED(hr), "DestroyViewWindow returned %#x\n", hr); @@ -201,7 +233,8 @@ static UINT_PTR CALLBACK create_view_window2_hook(HWND dlg, UINT msg, WPARAM wPa ok(SUCCEEDED(hr), "GetCurrentInfo returned %#x\n", hr); ok(folder_settings.ViewMode == FVM_DETAILS || broken(folder_settings.ViewMode == FVM_LIST), /* Win9x */ - "view mode is %d, expected %d\n", folder_settings.ViewMode, FVM_DETAILS); + "view mode is %d, expected FVM_DETAILS\n", + folder_settings.ViewMode); cleanup: if (shell_view2) IShellView2_Release(shell_view2); @@ -241,7 +274,7 @@ static void test_create_view_window2(void) ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = filename; - ofn.nMaxFile = 1042; + ofn.nMaxFile = 1024; ofn.lpfnHook = create_view_window2_hook; ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER; ret = GetOpenFileNameA(&ofn); @@ -258,7 +291,7 @@ static void test_create_view_template(void) ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = filename; - ofn.nMaxFile = 1042; + ofn.nMaxFile = 1024; ofn.lpfnHook = (LPOFNHOOKPROC)template_hook; ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE; ofn.hInstance = GetModuleHandleA(NULL); @@ -270,9 +303,694 @@ static void test_create_view_template(void) ok(!ret, "CommDlgExtendedError returned %#x\n", ret); } +/* test cases for resizing of the file dialog */ +struct { + DWORD flags; + int resize_folderchange;/* change in CDN_FOLDERCHANGE handler */ + int resize_timer1; /* change in first WM_TIMER handler */ + int resize_check; /* expected change (in second WM_TIMER handler) */ + BOOL todo; /* mark that test todo_wine */ + BOOL testcontrols; /* test resizing and moving of the controls */ +} resize_testcases[] = { + { 0 , 10, 10, 20,FALSE,FALSE}, /* 0 */ + { 0 ,-10,-10,-20,FALSE,FALSE}, + { OFN_ENABLESIZING , 0, 0, 0,FALSE,FALSE}, + { OFN_ENABLESIZING , 0,-10, 0,FALSE,FALSE}, + { OFN_ENABLESIZING , 0, 10, 10,FALSE, TRUE}, + { OFN_ENABLESIZING ,-10, 0, 10,FALSE,FALSE}, /* 5 */ + { OFN_ENABLESIZING , 10, 0, 10,FALSE,FALSE}, + { OFN_ENABLESIZING , 0, 10, 20,FALSE,FALSE}, + /* mark the end */ + { 0xffffffff } +}; + +static LONG_PTR WINAPI resize_template_hook(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static RECT initrc, rc; + static int index, count; + static int gotSWP_bottom, gotShowWindow; + HWND parent = GetParent( dlg); + int resize; +#define MAXNRCTRLS 30 + static RECT ctrlrcs[MAXNRCTRLS]; + static int ctrlids[MAXNRCTRLS]; + static HWND ctrls[MAXNRCTRLS]; + static int nrctrls; + + switch( msg) + { + case WM_INITDIALOG: + { + DWORD style; + + index = ((OPENFILENAME*)lParam)->lCustData; + count = 0; + gotSWP_bottom = gotShowWindow = 0; + /* test style */ + style = GetWindowLong( parent, GWL_STYLE); + if( resize_testcases[index].flags & OFN_ENABLESIZING) + if( !(style & WS_SIZEBOX)) { + win_skip( "OFN_ENABLESIZING flag not supported.\n"); + resizesupported = FALSE; + PostMessage( parent, WM_COMMAND, IDCANCEL, 0); + } else + ok( style & WS_SIZEBOX, + "testid %d: dialog should have a WS_SIZEBOX style.\n", index); + else + ok( !(style & WS_SIZEBOX), + "testid %d: dialog should not have a WS_SIZEBOX style.\n", index); + break; + } + case WM_NOTIFY: + { + if(( (LPNMHDR)lParam)->code == CDN_FOLDERCHANGE){ + GetWindowRect( parent, &initrc); + if( (resize = resize_testcases[index].resize_folderchange)){ + MoveWindow( parent, initrc.left,initrc.top, initrc.right - initrc.left + resize, + initrc.bottom - initrc.top + resize, TRUE); + } + SetTimer( dlg, 0, 100, 0); + } + break; + } + case WM_TIMER: + { + if( count == 0){ + /* store the control rectangles */ + if( resize_testcases[index].testcontrols) { + HWND ctrl; + int i; + for( i = 0, ctrl = GetWindow( parent, GW_CHILD); + i < MAXNRCTRLS && ctrl; + i++, ctrl = GetWindow( ctrl, GW_HWNDNEXT)) { + ctrlids[i] = GetDlgCtrlID( ctrl); + GetWindowRect( ctrl, &ctrlrcs[i]); + MapWindowPoints( NULL, parent, (LPPOINT) &ctrlrcs[i], 2); + ctrls[i] = ctrl; + } + nrctrls = i; + } + if( (resize = resize_testcases[index].resize_timer1)){ + GetWindowRect( parent, &rc); + MoveWindow( parent, rc.left,rc.top, rc.right - rc.left + resize, + rc.bottom - rc.top + resize, TRUE); + } + } else if( count == 1){ + resize = resize_testcases[index].resize_check; + GetWindowRect( parent, &rc); + if( resize_testcases[index].todo){ + todo_wine { + ok( resize == rc.right - rc.left - initrc.right + initrc.left, + "testid %d size-x change %d expected %d\n", index, + rc.right - rc.left - initrc.right + initrc.left, resize); + ok( resize == rc.bottom - rc.top - initrc.bottom + initrc.top, + "testid %d size-y change %d expected %d\n", index, + rc.bottom - rc.top - initrc.bottom + initrc.top, resize); + } + }else{ + ok( resize == rc.right - rc.left - initrc.right + initrc.left, + "testid %d size-x change %d expected %d\n", index, + rc.right - rc.left - initrc.right + initrc.left, resize); + ok( resize == rc.bottom - rc.top - initrc.bottom + initrc.top, + "testid %d size-y change %d expected %d\n", index, + rc.bottom - rc.top - initrc.bottom + initrc.top, resize); + } + if( resize_testcases[index].testcontrols) { + int i; + RECT rc; + for( i = 0; i < nrctrls; i++) { + GetWindowRect( ctrls[i], &rc); + MapWindowPoints( NULL, parent, (LPPOINT) &rc, 2); + switch( ctrlids[i]){ + +/* test if RECT R1, moved and sized result in R2 */ +#define TESTRECTS( R1, R2, Mx, My, Sx, Sy) \ + ((R1).left + (Mx) ==(R2).left \ + &&(R1).top + (My) ==(R2).top \ + &&(R1).right + (Mx) + (Sx) == (R2).right \ + &&(R1).bottom + (My) + (Sy) ==(R2).bottom) + + /* sized horizontal and moved vertical */ + case cmb1: + case edt1: + ok( TESTRECTS( ctrlrcs[i], rc, 0, 10, 10, 0) || + broken(TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0)),/*win98*/ + "control id %03x should have sized horizontally and moved vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* sized horizontal and vertical */ + case lst2: + ok( TESTRECTS( ctrlrcs[i], rc, 0, 0, 10, 10), + "control id %03x should have sized horizontally and vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* moved horizontal and vertical */ + case IDCANCEL: + case pshHelp: + ok( TESTRECTS( ctrlrcs[i], rc, 10, 10, 0, 0) || + broken(TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0)),/*win98*/ + "control id %03x should have moved horizontally and vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* moved vertically */ + case chx1: + case stc2: + case stc3: + ok( TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0), + "control id %03x should have moved vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* resized horizontal */ + case cmb2: /* aka IDC_LOOKIN */ + ok( TESTRECTS( ctrlrcs[i], rc, 0, 0, 10, 0)|| + TESTRECTS( ctrlrcs[i], rc, 0, 0, 0, 0), /* Vista and higher */ + "control id %03x should have resized horizontally, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* non moving non sizing controls */ + case stc4: + ok( TESTRECTS( rc, ctrlrcs[i], 0, 0, 0, 0), + "control id %03x was moved/resized, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* todo_wine: non moving non sizing controls */ + case lst1: +todo_wine + ok( TESTRECTS( rc, ctrlrcs[i], 0, 0, 0, 0), + "control id %03x was moved/resized, before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); + break; + /* don't test: id is not unique */ + case IDOK: + case stc1: + case 0: + case -1: + break; + default: + trace("untested control id %03x before %d,%d-%d,%d after %d,%d-%d,%d\n", + ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top, + ctrlrcs[i].right, ctrlrcs[i].bottom, + rc.left, rc.top, rc.right, rc.bottom); +#undef TESTRECTS +#undef MAXNRCTRLS + } + } + } + KillTimer( dlg, 0); + PostMessage( parent, WM_COMMAND, IDCANCEL, 0); + } + count++; + } + break; + case WM_WINDOWPOSCHANGING: + { + WINDOWPOS *pwp = (WINDOWPOS *)lParam; + if( !index && pwp->hwndInsertAfter == HWND_BOTTOM){ + gotSWP_bottom = 1; + ok( gotShowWindow == 0, "The WM_WINDOWPOSCHANGING message came after a WM_SHOWWINDOW message\n"); + } + } + break; + case WM_SHOWWINDOW: + { + if( !index){ + gotShowWindow = 1; + ok( gotSWP_bottom == 1, "No WM_WINDOWPOSCHANGING message came before a WM_SHOWWINDOW message\n"); + } + } + break; + } + return 0; +} + +static void test_resize(void) +{ + OPENFILENAME ofn = { sizeof(OPENFILENAME)}; + char filename[1024] = {0}; + DWORD ret; + int i; + + ofn.lpstrFile = filename; + ofn.nMaxFile = 1024; + ofn.lpfnHook = (LPOFNHOOKPROC) resize_template_hook; + ofn.hInstance = GetModuleHandle(NULL); + ofn.lpTemplateName = "template_sz"; + for( i = 0; resize_testcases[i].flags != 0xffffffff; i++) { + ofn.lCustData = i; + ofn.Flags = resize_testcases[i].flags | + OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE | OFN_SHOWHELP ; + ret = GetOpenFileName(&ofn); + ok(!ret, "GetOpenFileName returned %#x\n", ret); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + } +} + +/* test cases for control message IDOK */ +/* Show case for bug #19079 */ +static struct { + int retval; /* return code of the message handler */ + BOOL setmsgresult; /* set the result in the DWLP_MSGRESULT */ + BOOL usemsgokstr; /* use the FILEOKSTRING message instead of WM_NOTIFY:CDN_FILEOK */ + BOOL do_subclass; /* subclass the dialog hook procedure */ + BOOL expclose; /* is the dialog expected to close ? */ + BOOL actclose; /* has the dialog actually closed ? */ +} ok_testcases[] = { + { 0, FALSE, FALSE, FALSE, TRUE}, + { 0, TRUE, FALSE, FALSE, TRUE}, + { 0, FALSE, FALSE, TRUE, TRUE}, + { 0, TRUE, FALSE, TRUE, TRUE}, + { 1, FALSE, FALSE, FALSE, TRUE}, + { 1, TRUE, FALSE, FALSE, FALSE}, + { 1, FALSE, FALSE, TRUE, FALSE}, + { 1, TRUE, FALSE, TRUE, FALSE}, + /* FILEOKSTRING tests */ + { 1, TRUE, TRUE, FALSE, FALSE}, + { 1, FALSE, TRUE, TRUE, FALSE}, + /* mark the end */ + { -1 } +}; + +/* test_ok_wndproc can be used as hook procedure or a subclass + * window proc for the file dialog */ +static LONG_PTR WINAPI test_ok_wndproc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND parent = GetParent( dlg); + static int index; + static UINT msgFILEOKSTRING; + if (msg == WM_INITDIALOG) + { + index = ((OPENFILENAME*)lParam)->lCustData; + ok_testcases[index].actclose = TRUE; + msgFILEOKSTRING = RegisterWindowMessageA( FILEOKSTRING); + } + if( msg == WM_NOTIFY) { + if(((LPNMHDR)lParam)->code == CDN_FOLDERCHANGE) { + SetTimer( dlg, 0, 100, 0); + PostMessage( parent, WM_COMMAND, IDOK, 0); + return FALSE; + } else if(((LPNMHDR)lParam)->code == CDN_FILEOK) { + if( ok_testcases[index].usemsgokstr) + return FALSE; + if( ok_testcases[index].setmsgresult) + SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval); + return ok_testcases[index].retval; + } + } + if( msg == msgFILEOKSTRING) { + if( !ok_testcases[index].usemsgokstr) + return FALSE; + if( ok_testcases[index].setmsgresult) + SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval); + return ok_testcases[index].retval; + } + if( msg == WM_TIMER) { + /* the dialog did not close automatically */ + ok_testcases[index].actclose = FALSE; + KillTimer( dlg, 0); + PostMessage( parent, WM_COMMAND, IDCANCEL, 0); + return FALSE; + } + if( ok_testcases[index].do_subclass) + return DefWindowProc( dlg, msg, wParam, lParam); + return FALSE; +} + +static LONG_PTR WINAPI ok_template_hook(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_SETFONT) + SetWindowLongPtrA( dlg, GWLP_WNDPROC, (LONG_PTR) test_ok_wndproc); + return FALSE; +} + +static void test_ok(void) +{ + OPENFILENAME ofn = { sizeof(OPENFILENAME)}; + char filename[1024] = {0}; + char tmpfilename[ MAX_PATH]; + char curdir[MAX_PATH]; + int i; + DWORD ret; + + ok(GetCurrentDirectoryA(sizeof(curdir), curdir) != 0, "Failed to get current dir err %d\n", GetLastError()); + if (!GetTempFileNameA(".", "txt", 0, tmpfilename)) { + skip("Failed to create a temporary file name\n"); + return; + } + ofn.lpstrFile = filename; + ofn.nMaxFile = 1024; + ofn.hInstance = GetModuleHandle(NULL); + ofn.lpTemplateName = "template1"; + ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE ; + for( i = 0; ok_testcases[i].retval != -1; i++) { + strcpy( filename, tmpfilename); + ofn.lCustData = i; + ofn.lpfnHook = ok_testcases[i].do_subclass + ? (LPOFNHOOKPROC) ok_template_hook + : (LPOFNHOOKPROC) test_ok_wndproc; + ret = GetOpenFileNameA(&ofn); + ok( ok_testcases[i].expclose == ok_testcases[i].actclose, + "testid %d: Open File dialog should %shave closed.\n", i, + ok_testcases[i].expclose ? "" : "NOT "); + ok(ret == ok_testcases[i].expclose, "testid %d: GetOpenFileName returned %#x\n", i, ret); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + ok(SetCurrentDirectoryA(curdir), "Failed to restore current dir err %d\n", GetLastError()); + } + ret = DeleteFileA( tmpfilename); + ok( ret, "Failed to delete temporary file %s err %d\n", tmpfilename, GetLastError()); +} + +/* test arranging with a custom template */ +typedef struct { + int x, y; /* left, top coordinates */ + int cx, cy; /* width and height */ +} posz; +static struct { + int nrcontrols; /* 0: no controls, 1: just the stc32 control 2: with button */ + posz poszDlg; + posz poszStc32; + posz poszBtn; + DWORD ofnflags; +} arrange_tests[] = { + /* do not change the first two cases: used to get the uncustomized sizes */ + { 0, {0},{0},{0},0 }, + { 0, {0},{0},{0}, OFN_SHOWHELP}, + /* two tests with just a subdialog, no controls */ + { 0, {0, 0, 316, 76},{0},{0},0 }, + { 0, {0, 0, 100, 76},{0},{0}, OFN_SHOWHELP}, + /* now with a control with id stc32 */ + { 1, {0, 0, 316, 76} ,{0, 0, 204, 76,},{0},0 }, /* bug #17748*/ + { 1, {0, 0, 316, 76} ,{0, 0, 204, 76,},{0}, OFN_SHOWHELP}, /* bug #17748*/ + /* tests with size of the stc32 control higher or wider then the standard dialog */ + { 1, {0, 0, 316, 170} ,{0, 0, 204, 170,},{0},0 }, + { 1, {0, 0, 316, 165} ,{0, 0, 411, 165,},{0}, OFN_SHOWHELP }, + /* move the stc32 control around */ + { 1, {0, 0, 300, 100} ,{73, 17, 50, 50,},{0},0 }, + /* add control */ + { 2, {0, 0, 280, 100} ,{0, 0, 50, 50,},{300,20,30,30},0 }, + /* enable resizing should make the dialog bigger */ + { 0, {0},{0},{0}, OFN_SHOWHELP|OFN_ENABLESIZING}, + /* mark the end */ + { -1 } +}; + +static LONG_PTR WINAPI template_hook_arrange(HWND dlgChild, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int index, fixhelp; + static posz posz0[2]; + static RECT clrcParent, clrcChild, rcStc32; + static HWND hwndStc32; + HWND dlgParent; + + dlgParent = GetParent( dlgChild); + if (msg == WM_INITDIALOG) { + index = ((OPENFILENAME*)lParam)->lCustData; + /* get the positions before rearrangement */ + GetClientRect( dlgParent, &clrcParent); + GetClientRect( dlgChild, &clrcChild); + hwndStc32 = GetDlgItem( dlgChild, stc32); + if( hwndStc32) GetWindowRect( hwndStc32, &rcStc32); + } + if (msg == WM_NOTIFY && ((LPNMHDR)lParam)->code == CDN_FOLDERCHANGE) { + RECT wrcParent; + + GetWindowRect( dlgParent, &wrcParent); + /* the fist two "tests" just save the dialogs position, with and without + * help button */ + if( index == 0) { + posz0[0].x = wrcParent.left; + posz0[0].y = wrcParent.top; + posz0[0].cx = wrcParent.right - wrcParent.left; + posz0[0].cy = wrcParent.bottom - wrcParent.top; + } else if( index == 1) { + posz0[1].x = wrcParent.left; + posz0[1].y = wrcParent.top; + posz0[1].cx = wrcParent.right - wrcParent.left; + posz0[1].cy = wrcParent.bottom - wrcParent.top; + fixhelp = posz0[1].cy - posz0[0].cy; + } else { + /* the real tests */ + int withhelp; + int expectx, expecty; + DWORD style; + + withhelp = (arrange_tests[index].ofnflags & OFN_SHOWHELP) != 0; + GetWindowRect( dlgParent, &wrcParent); + if( !hwndStc32) { + /* case with no custom subitem with stc32: + * default to all custom controls below the standard */ + expecty = posz0[withhelp].cy + clrcChild.bottom; + expectx = posz0[withhelp].cx; + } else { + /* special case: there is a control with id stc32 */ + /* expected height */ + expecty = posz0[withhelp].cy; + if( rcStc32.bottom - rcStc32.top > clrcParent.bottom) { + expecty += clrcChild.bottom - clrcParent.bottom; + if( !withhelp) expecty += fixhelp; + } + else + expecty += clrcChild.bottom - ( rcStc32.bottom - rcStc32.top) ; + /* expected width */ + expectx = posz0[withhelp].cx; + if( rcStc32.right - rcStc32.left > clrcParent.right) { + expectx += clrcChild.right - clrcParent.right; + } + else + expectx += clrcChild.right - ( rcStc32.right - rcStc32.left) ; + } + style = GetWindowLong( dlgParent, GWL_STYLE); + if( !(style & WS_SIZEBOX)) { + /* without the OFN_ENABLESIZING flag */ + ok( wrcParent.bottom - wrcParent.top == expecty, + "Wrong height of dialog %d, expected %d\n", + wrcParent.bottom - wrcParent.top, expecty); + ok( wrcParent.right - wrcParent.left == expectx, + "Wrong width of dialog %d, expected %d\n", + wrcParent.right - wrcParent.left, expectx); + } else todo_wine { + /* with the OFN_ENABLESIZING flag */ + ok( wrcParent.bottom - wrcParent.top > expecty, + "Wrong height of dialog %d, expected more than %d\n", + wrcParent.bottom - wrcParent.top, expecty); + ok( wrcParent.right - wrcParent.left > expectx, + "Wrong width of dialog %d, expected more than %d\n", + wrcParent.right - wrcParent.left, expectx); + } + + } + PostMessage( dlgParent, WM_COMMAND, IDCANCEL, 0); + } + return 0; +} + +static void test_arrange(void) +{ + OPENFILENAMEA ofn = {0}; + char filename[1024] = {0}; + DWORD ret; + HRSRC hRes; + HANDLE hDlgTmpl; + LPBYTE pv; + DLGTEMPLATE *template; + DLGITEMTEMPLATE *itemtemplateStc32, *itemtemplateBtn; + int i; + + /* load subdialog template into memory */ + hRes = FindResource( GetModuleHandle(NULL), "template_stc32", (LPSTR)RT_DIALOG); + hDlgTmpl = LoadResource( GetModuleHandle(NULL), hRes ); + /* get pointers to the structures for the dialog and the controls */ + pv = LockResource( hDlgTmpl ); + template = (DLGTEMPLATE*)pv; + if( template->x != 11111) { + win_skip("could not find the dialog template\n"); + return; + } + /* skip dialog template, menu, class and title */ + pv += sizeof(DLGTEMPLATE); + pv += 3 * sizeof(WORD); + /* skip font info */ + while( *(WORD*)pv) + pv += sizeof(WORD); + pv += sizeof(WORD); + /* align on 32 bit boundaries */ + pv = (LPBYTE)(((UINT_PTR)pv + 3 ) & ~3); + itemtemplateStc32 = (DLGITEMTEMPLATE*)pv; + if( itemtemplateStc32->x != 22222) { + win_skip("could not find the first item template\n"); + return; + } + /* skip itemtemplate, class, title and creation data */ + pv += sizeof(DLGITEMTEMPLATE); + pv += 4 * sizeof(WORD); + /* align on 32 bit boundaries */ + pv = (LPBYTE)(((UINT_PTR)pv + 3 ) & ~3); + itemtemplateBtn = (DLGITEMTEMPLATE*)pv; + if( itemtemplateBtn->x != 12345) { + win_skip("could not find the second item template\n"); + return; + } + + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = filename; + ofn.nMaxFile = 1024; + ofn.lpfnHook = (LPOFNHOOKPROC)template_hook_arrange; + ofn.hInstance = hDlgTmpl; + ofn.lpstrFilter="text\0*.txt\0All\0*\0\0"; + for( i = 0; arrange_tests[i].nrcontrols != -1; i++) { + ofn.lCustData = i; + ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATEHANDLE | OFN_HIDEREADONLY | + arrange_tests[i].ofnflags; + template->cdit = arrange_tests[i].nrcontrols; + template->x = arrange_tests[i].poszDlg.x; + template->y = arrange_tests[i].poszDlg.y; + template->cx = arrange_tests[i].poszDlg.cx; + template->cy = arrange_tests[i].poszDlg.cy; + itemtemplateStc32->x = arrange_tests[i].poszStc32.x; + itemtemplateStc32->y = arrange_tests[i].poszStc32.y; + itemtemplateStc32->cx = arrange_tests[i].poszStc32.cx; + itemtemplateStc32->cy = arrange_tests[i].poszStc32.cy; + itemtemplateBtn->x = arrange_tests[i].poszBtn.x; + itemtemplateBtn->y = arrange_tests[i].poszBtn.y; + itemtemplateBtn->cx = arrange_tests[i].poszBtn.cx; + itemtemplateBtn->cy = arrange_tests[i].poszBtn.cy; + ret = GetOpenFileNameA(&ofn); + ok(!ret, "GetOpenFileNameA returned %#x\n", ret); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + } +} + +static CHAR SYSDIR[MAX_PATH]; + +static UINT_PTR CALLBACK path_hook_proc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LPNMHDR nmh; + + if( msg == WM_NOTIFY) + { + nmh = (LPNMHDR) lParam; + if( nmh->code == CDN_INITDONE) + { + PostMessage( GetParent(hDlg), WM_COMMAND, IDCANCEL, FALSE); + } + else if ( nmh->code == CDN_FOLDERCHANGE) + { + char buf[1024]; + int ret; + + memset(buf, 0x66, sizeof(buf)); + ret = SendMessageA( GetParent(hDlg), CDM_GETFOLDERPATH, sizeof(buf), (LPARAM)buf); + ok(!lstrcmpiA(SYSDIR, buf), "Expected '%s', got '%s'\n", SYSDIR, buf); + ok(lstrlenA(SYSDIR) + 1 == ret, "Expected %d, got %d\n", lstrlenA(SYSDIR) + 1, ret); + } + } + + return 0; +} + +static void test_getfolderpath(void) +{ + OPENFILENAMEA ofn; + BOOL result; + char szFileName[MAX_PATH] = ""; + char szInitialDir[MAX_PATH]; + + /* We need to pick a different directory as the other tests because of new + * Windows 7 behavior. + */ + GetSystemDirectory(szInitialDir, MAX_PATH); + lstrcpyA(SYSDIR, szInitialDir); + + ZeroMemory(&ofn, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = NULL; + ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLEHOOK; + ofn.lpstrDefExt = "txt"; + ofn.lpfnHook = path_hook_proc; + ofn.lpstrInitialDir = szInitialDir; + + result = GetOpenFileNameA(&ofn); + ok(0 == result, "expected 0, got %d\n", result); + ok(0 == CommDlgExtendedError(), "expected 0, got %d\n", + CommDlgExtendedError()); + + result = GetSaveFileNameA(&ofn); + ok(0 == result, "expected 0, got %d\n", result); + ok(0 == CommDlgExtendedError(), "expected 0, got %d\n", + CommDlgExtendedError()); +} + +static void test_resizable2(void) +{ + OPENFILENAMEA ofn = {0}; + char filename[1024] = "pls press Enter if sizable, Esc otherwise"; + DWORD ret; + + /* interactive because there is no hook function */ + if( !winetest_interactive) { + skip( "some interactive resizable dialog tests (set WINETEST_INTERACTIVE=1)\n"); + return; + } + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = filename; + ofn.nMaxFile = 1024; + ofn.lpfnHook = NULL; + ofn.hInstance = GetModuleHandleA(NULL); + ofn.lpTemplateName = "template1"; + ofn.Flags = OFN_EXPLORER; +#define ISSIZABLE 1 + ret = GetOpenFileNameA(&ofn); + ok( ret == ISSIZABLE, "File Dialog should have been sizable\n"); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + ofn.Flags = OFN_EXPLORER | OFN_ENABLETEMPLATE; + ret = GetOpenFileNameA(&ofn); + ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n"); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + ofn.Flags = OFN_EXPLORER | OFN_ENABLETEMPLATEHANDLE; + ofn.hInstance = LoadResource( GetModuleHandle(NULL), FindResource( GetModuleHandle(NULL), "template1", (LPSTR)RT_DIALOG)); + ofn.lpTemplateName = NULL; + ret = GetOpenFileNameA(&ofn); + ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n"); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); + ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK; + ret = GetOpenFileNameA(&ofn); + ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n"); + ret = CommDlgExtendedError(); + ok(!ret, "CommDlgExtendedError returned %#x\n", ret); +#undef ISSIZABLE +} + START_TEST(filedlg) { test_DialogCancel(); test_create_view_window2(); test_create_view_template(); + test_arrange(); + test_resize(); + test_ok(); + test_getfolderpath(); + if( resizesupported) test_resizable2(); } diff --git a/rostests/winetests/comdlg32/fontdlg.c b/rostests/winetests/comdlg32/fontdlg.c new file mode 100644 index 00000000000..57c1d908214 --- /dev/null +++ b/rostests/winetests/comdlg32/fontdlg.c @@ -0,0 +1,150 @@ +/* + * Unit test suite for comdlg32 API functions: font dialogs + * + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wingdi.h" +#include "winspool.h" +#include "winuser.h" +#include "objbase.h" + +#include "commdlg.h" + +#include "wine/test.h" + +static int get_dpiy(void) +{ + HDC hdc; + int result; + + hdc = GetDC(0); + result = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(0, hdc); + + return result; +} + +static HDC get_printer_ic(void) +{ + PRINTER_INFO_2A *info; + DWORD info_size, num_printers=0; + BOOL ret; + HDC result=NULL; + + EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &info_size, &num_printers); + + if (info_size == 0) + return NULL; + + info = HeapAlloc(GetProcessHeap(), 0, info_size); + + ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)info, info_size, &info_size, &num_printers); + + if (ret) + result = CreateICA(info->pDriverName, info->pPrinterName, NULL, NULL); + + HeapFree(GetProcessHeap(), 0, info); + + return result; +} + +static UINT_PTR CALLBACK CFHookProcOK(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch (msg) + { + case WM_INITDIALOG: + PostMessageA(hdlg, WM_COMMAND, IDOK, FALSE); + return 0; + default: + return 0; + } +} + +static void test_ChooseFontA(void) +{ + LOGFONTA lfa; + CHOOSEFONTA cfa; + BOOL ret; + int dpiy = get_dpiy(); + int expected_pointsize, expected_lfheight; + HDC printer_ic; + + memset(&lfa, 0, sizeof(LOGFONTA)); + lfa.lfHeight = -16; + lfa.lfWeight = FW_NORMAL; + strcpy(lfa.lfFaceName, "Symbol"); + + memset(&cfa, 0, sizeof(CHOOSEFONTA)); + cfa.lStructSize = sizeof(cfa); + cfa.lpLogFont = &lfa; + cfa.Flags = CF_ENABLEHOOK|CF_INITTOLOGFONTSTRUCT|CF_SCREENFONTS; + cfa.lpfnHook = CFHookProcOK; + + ret = ChooseFontA(&cfa); + + expected_pointsize = MulDiv(16, 72, dpiy) * 10; + expected_lfheight = -MulDiv(expected_pointsize, dpiy, 720); + + ok(ret == TRUE, "ChooseFontA returned FALSE\n"); + ok(cfa.iPointSize == expected_pointsize, "Expected %i, got %i\n", expected_pointsize, cfa.iPointSize); + ok(lfa.lfHeight == expected_lfheight, "Expected %i, got %i\n", expected_lfheight, lfa.lfHeight); + ok(lfa.lfWeight == FW_NORMAL, "Expected FW_NORMAL, got %i\n", lfa.lfWeight); + ok(strcmp(lfa.lfFaceName, "Symbol") == 0, "Expected Symbol, got %s\n", lfa.lfFaceName); + + printer_ic = get_printer_ic(); + if (!printer_ic) + skip("can't get a DC for a local printer\n"); + else + { + memset(&lfa, 0, sizeof(LOGFONTA)); + lfa.lfHeight = -16; + lfa.lfWeight = FW_NORMAL; + strcpy(lfa.lfFaceName, "Symbol"); + + memset(&cfa, 0, sizeof(CHOOSEFONTA)); + cfa.lStructSize = sizeof(cfa); + cfa.lpLogFont = &lfa; + cfa.Flags = CF_ENABLEHOOK|CF_INITTOLOGFONTSTRUCT|CF_PRINTERFONTS; + cfa.hDC = printer_ic; + cfa.lpfnHook = CFHookProcOK; + + ret = ChooseFontA(&cfa); + + expected_pointsize = MulDiv(16, 72, dpiy) * 10; + expected_lfheight = -MulDiv(expected_pointsize, dpiy, 720); + + ok(ret == TRUE, "ChooseFontA returned FALSE\n"); + ok(cfa.iPointSize == expected_pointsize, "Expected %i, got %i\n", expected_pointsize, cfa.iPointSize); + ok(lfa.lfHeight == expected_lfheight, "Expected %i, got %i\n", expected_lfheight, lfa.lfHeight); + ok(lfa.lfWeight == FW_NORMAL, "Expected FW_NORMAL, got %i\n", lfa.lfWeight); + ok(strcmp(lfa.lfFaceName, "Symbol") == 0, "Expected Symbol, got %s\n", lfa.lfFaceName); + + DeleteDC(printer_ic); + } +} + +START_TEST(fontdlg) +{ + test_ChooseFontA(); +} diff --git a/rostests/winetests/comdlg32/printdlg.c b/rostests/winetests/comdlg32/printdlg.c index ec63da9a6c7..f021b019299 100644 --- a/rostests/winetests/comdlg32/printdlg.c +++ b/rostests/winetests/comdlg32/printdlg.c @@ -246,6 +246,11 @@ static void test_PrintDlgExW(void) PrintDlg(NULL); SetLastError(0xdeadbeef); res = pPrintDlgExW(NULL); + if(res == E_NOTIMPL) + { + win_skip("PrintDlgExW returns not implemented\n"); + return; + } ok( (res == E_INVALIDARG), "got 0x%x with %u and %u (expected 'E_INVALIDARG')\n", res, GetLastError(), CommDlgExtendedError()); @@ -318,6 +323,8 @@ static void test_abort_proc(void) ok(DeleteFileA(filename), "Failed to delete temporary file\n"); return; } + GlobalFree(pd.hDevMode); + GlobalFree(pd.hDevNames); ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n"); if (!(print_dc = pd.hDC)) @@ -346,25 +353,19 @@ static void test_abort_proc(void) goto end; } - ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n"); - abort_proc_called = FALSE; + /* StartDoc may or may not call abort proc */ + abort_proc_called = FALSE; ok(StartPage(print_dc) > 0, "StartPage failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n"); abort_proc_called = FALSE; + /* following functions sometimes call abort proc too */ ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n"); - ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n"); - abort_proc_called = FALSE; - ok(EndPage(print_dc) > 0, "EndPage failed\n"); - ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n"); - abort_proc_called = FALSE; - ok(EndDoc(print_dc) > 0, "EndDoc failed\n"); - ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n"); - abort_proc_called = FALSE; + abort_proc_called = FALSE; ok(DeleteDC(print_dc), "DeleteDC failed\n"); ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n"); abort_proc_called = FALSE; diff --git a/rostests/winetests/comdlg32/rsrc.rc b/rostests/winetests/comdlg32/rsrc.rc index 51415fddb26..65e7972ffa4 100644 --- a/rostests/winetests/comdlg32/rsrc.rc +++ b/rostests/winetests/comdlg32/rsrc.rc @@ -32,3 +32,28 @@ FONT 8, "MS Shell Dlg" LTEXT "",-1,28,16,204,31 EDITTEXT 56,65,2,200,12,ES_AUTOHSCROLL } + +/* Used by the resize file dialog tests. + * Keep this template small or get failures + * resizing on small desk tops. + * This will work with 640x480 pixels + */ +TEMPLATE_SZ DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 300, 40 +STYLE WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +{ + LTEXT "Path:",-1,28,4,36,8 + LTEXT "Text1",-1,4,16,20,40 + LTEXT "Text2",-1,232,20,65,8 + LTEXT "",-1,28,16,204,31 + EDITTEXT 56,65,2,200,12,ES_AUTOHSCROLL +} + +/* note: the test program will modify coordinates and nr of controls in this template */ +TEMPLATE_STC32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 11111, 0, 316, 76 +STYLE WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +{ + LTEXT "", 1119, 22222, 0, 204, 76 + PUSHBUTTON "TEST", -1, 12345, 0, 20, 20 +} diff --git a/rostests/winetests/crypt32/chain.c b/rostests/winetests/crypt32/chain.c index a626b82c4fe..f9ccaed78b1 100644 --- a/rostests/winetests/crypt32/chain.c +++ b/rostests/winetests/crypt32/chain.c @@ -58,6 +58,8 @@ static VOID (WINAPI *pCertFreeCertificateChain)(PCCERT_CHAIN_CONTEXT); static VOID (WINAPI *pCertFreeCertificateChainEngine)(HCERTCHAINENGINE); static BOOL (WINAPI *pCertVerifyCertificateChainPolicy)(LPCSTR,PCCERT_CHAIN_CONTEXT,PCERT_CHAIN_POLICY_PARA,PCERT_CHAIN_POLICY_STATUS); +#define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0) + static void testCreateCertChainEngine(void) { @@ -3883,19 +3885,19 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, if (check->todo & TODO_POLICY) todo_wine ok(ret, "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, GetLastError()); else { if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) { skip("%d: missing policy %s, skipping test\n", testIndex, - HIWORD(policy) ? policy : num_to_str(LOWORD(policy))); + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy); pCertFreeCertificateChain(chain); return; } ok(ret, "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), testIndex, + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, GetLastError()); } if (ret) @@ -3906,7 +3908,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.dwError == check->brokenStatus->dwError)), "%s[%d]: expected %08x, got %08x\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.dwError, policyStatus.dwError); else ok(policyStatus.dwError == check->status.dwError || @@ -3914,12 +3916,12 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.dwError == check->brokenStatus->dwError)), "%s[%d]: expected %08x, got %08x\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.dwError, policyStatus.dwError); if (policyStatus.dwError != check->status.dwError) { skip("%s[%d]: error %08x doesn't match expected %08x, not checking indexes\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, policyStatus.dwError, check->status.dwError); pCertFreeCertificateChain(chain); return; @@ -3930,7 +3932,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.lChainIndex == check->brokenStatus->lChainIndex)), "%s[%d]: expected %d, got %d\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.lChainIndex, policyStatus.lChainIndex); else @@ -3938,7 +3940,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.lChainIndex == check->brokenStatus->lChainIndex)), "%s[%d]: expected %d, got %d\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.lChainIndex, policyStatus.lChainIndex); if (check->todo & TODO_ELEMENTS) @@ -3947,7 +3949,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.lElementIndex == check->brokenStatus->lElementIndex)), "%s[%d]: expected %d, got %d\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.lElementIndex, policyStatus.lElementIndex); else @@ -3955,7 +3957,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, (check->brokenStatus && broken(policyStatus.lElementIndex == check->brokenStatus->lElementIndex)), "%s[%d]: expected %d, got %d\n", - HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, check->status.lElementIndex, policyStatus.lElementIndex); } diff --git a/rostests/winetests/crypt32/main.c b/rostests/winetests/crypt32/main.c index 9b622bbbd08..7c11e8e2ee3 100644 --- a/rostests/winetests/crypt32/main.c +++ b/rostests/winetests/crypt32/main.c @@ -254,10 +254,8 @@ static void test_cryptTls(void) ret = pI_CryptFreeTls(index, 0); ok(ret, "I_CryptFreeTls failed: %08x\n", GetLastError()); ret = pI_CryptFreeTls(index, 0); - /* Not sure if this fails because TlsFree should fail, so leave as - * todo for now. - */ - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, + ok(!ret, "I_CryptFreeTls succeeded\n"); + ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); } /* Similar pass, check I_CryptDetachTls */ diff --git a/rostests/winetests/crypt32/msg.c b/rostests/winetests/crypt32/msg.c index 8ab5625fd8e..39662ebe8f2 100644 --- a/rostests/winetests/crypt32/msg.c +++ b/rostests/winetests/crypt32/msg.c @@ -2572,8 +2572,8 @@ static void test_decode_msg_get_param(void) sizeof(signedKeyIdEmptyContent), TRUE); if (!ret && GetLastError() == OSS_DATA_ERROR) { - /* Subsequent tests crashes on some Win9x, so bail out */ CryptMsgClose(msg); + win_skip("Subsequent tests crash on some Win9x\n"); return; } ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); diff --git a/rostests/winetests/gdiplus/brush.c b/rostests/winetests/gdiplus/brush.c index 0ee4dd485a2..0effcf40fd6 100644 --- a/rostests/winetests/gdiplus/brush.c +++ b/rostests/winetests/gdiplus/brush.c @@ -646,6 +646,61 @@ static void test_linelinearblend(void) expect(Ok, status); } +static void test_gradientsurroundcolorcount(void) +{ + GpStatus status; + GpPathGradient *grad; + ARGB *color; + INT count = 3; + + status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad); + expect(Ok, status); + + color = GdipAlloc(sizeof(ARGB[3])); + + status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count); + expect(InvalidParameter, status); + GdipFree(color); + + count = 2; + + color = GdipAlloc(sizeof(ARGB[2])); + + color[0] = 0x00ff0000; + color[1] = 0x0000ff00; + + status = GdipSetPathGradientSurroundColorsWithCount(NULL, color, &count); + expect(InvalidParameter, status); + + status = GdipSetPathGradientSurroundColorsWithCount(grad, NULL, &count); + expect(InvalidParameter, status); + + /* WinXP crashes on this test */ + if(0) + { + status = GdipSetPathGradientSurroundColorsWithCount(grad, color, NULL); + expect(InvalidParameter, status); + } + + status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count); + todo_wine expect(Ok, status); + expect(2, count); + + status = GdipGetPathGradientSurroundColorCount(NULL, &count); + expect(InvalidParameter, status); + + status = GdipGetPathGradientSurroundColorCount(grad, NULL); + expect(InvalidParameter, status); + + count = 0; + status = GdipGetPathGradientSurroundColorCount(grad, &count); + todo_wine expect(Ok, status); + todo_wine expect(2, count); + + GdipFree(color); + GdipDeleteBrush((GpBrush*)grad); +} + START_TEST(brush) { struct GdiplusStartupInput gdiplusStartupInput; @@ -669,6 +724,7 @@ START_TEST(brush) test_gradientgetrect(); test_lineblend(); test_linelinearblend(); + test_gradientsurroundcolorcount(); GdiplusShutdown(gdiplusToken); } diff --git a/rostests/winetests/gdiplus/font.c b/rostests/winetests/gdiplus/font.c index 7b95d4c55ab..80f11bc0032 100644 --- a/rostests/winetests/gdiplus/font.c +++ b/rostests/winetests/gdiplus/font.c @@ -18,11 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "windows.h" #include "gdiplus.h" #include "wine/test.h" #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) +#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got) static const WCHAR arial[] = {'A','r','i','a','l','\0'}; static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'}; @@ -189,12 +192,9 @@ static void test_fontfamily (void) expect (FontFamilyNotFound, stat); /* Bitmap fonts are not found */ -todo_wine -{ stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family); expect (FontFamilyNotFound, stat); if(stat == Ok) GdipDeleteFontFamily(family); -} stat = GdipCreateFontFamilyFromName (arial, NULL, &family); if(stat == FontFamilyNotFound) @@ -345,6 +345,78 @@ static void test_installedfonts (void) ok (collection != NULL, "got NULL font collection\n"); } +static void test_heightgivendpi(void) +{ + GpStatus stat; + GpFont* font = NULL; + GpFontFamily* fontfamily = NULL; + REAL height; + + stat = GdipCreateFontFamilyFromName(arial, NULL, &fontfamily); + if(stat == FontFamilyNotFound) + { + skip("Arial not installed\n"); + return; + } + expect(Ok, stat); + + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font); + expect(Ok, stat); + + stat = GdipGetFontHeightGivenDPI(NULL, 96, &height); + expect(InvalidParameter, stat); + + stat = GdipGetFontHeightGivenDPI(font, 96, NULL); + expect(InvalidParameter, stat); + + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)34.497070, height); + GdipDeleteFont(font); + + height = 12345; + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font); + expect(Ok, stat); + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)34.497070, height); + GdipDeleteFont(font); + + height = 12345; + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font); + expect(Ok, stat); + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)45.996094, height); + GdipDeleteFont(font); + + height = 12345; + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font); + expect(Ok, stat); + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)3311.718750, height); + GdipDeleteFont(font); + + height = 12345; + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font); + expect(Ok, stat); + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)11.039062, height); + GdipDeleteFont(font); + + height = 12345; + stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font); + expect(Ok, stat); + stat = GdipGetFontHeightGivenDPI(font, 96, &height); + expect(Ok, stat); + expectf((REAL)130.382614, height); + GdipDeleteFont(font); + + GdipDeleteFontFamily(fontfamily); +} + START_TEST(font) { struct GdiplusStartupInput gdiplusStartupInput; @@ -363,6 +435,7 @@ START_TEST(font) test_fontfamily_properties(); test_getgenerics(); test_installedfonts(); + test_heightgivendpi(); GdiplusShutdown(gdiplusToken); } diff --git a/rostests/winetests/gdiplus/graphics.c b/rostests/winetests/gdiplus/graphics.c index b2dc9b299fb..57ce638093c 100644 --- a/rostests/winetests/gdiplus/graphics.c +++ b/rostests/winetests/gdiplus/graphics.c @@ -25,14 +25,17 @@ #include #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) -#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got) +#define expectf_(expected, got, precision) ok(fabs(expected - got) < precision, "Expected %.2f, got %.2f\n", expected, got) +#define expectf(expected, got) expectf_(expected, got, 0.0001) #define TABLE_LEN (23) +static HWND hwnd; + static void test_constructor_destructor(void) { GpStatus stat; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); stat = GdipCreateFromHDC(NULL, &graphics); expect(OutOfMemory, stat); @@ -56,7 +59,7 @@ static void test_constructor_destructor(void) stat = GdipDeleteGraphics(NULL); expect(InvalidParameter, stat); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } typedef struct node{ @@ -115,7 +118,7 @@ static void test_save_restore(void) InterpolationMode mode; GpGraphics *graphics1, *graphics2; node * state_log = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); state_a = state_b = state_c = 0xdeadbeef; /* Invalid saving. */ @@ -224,7 +227,7 @@ static void test_save_restore(void) todo_wine check_no_duplicates(state_log); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawArc(void) @@ -232,7 +235,7 @@ static void test_GdipDrawArc(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* make a graphics object and pen object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -268,7 +271,7 @@ static void test_GdipDrawArc(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawArcI(void) @@ -276,7 +279,7 @@ static void test_GdipDrawArcI(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* make a graphics object and pen object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -312,7 +315,7 @@ static void test_GdipDrawArcI(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_BeginContainer2(void) @@ -334,7 +337,7 @@ static void test_BeginContainer2(void) GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -497,7 +500,7 @@ static void test_BeginContainer2(void) expect(Ok, status); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawBezierI(void) @@ -505,7 +508,7 @@ static void test_GdipDrawBezierI(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* make a graphics object and pen object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -535,7 +538,7 @@ static void test_GdipDrawBezierI(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurve3(void) @@ -543,7 +546,7 @@ static void test_GdipDrawCurve3(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPointF points[3]; points[0].X = 0; @@ -615,7 +618,7 @@ static void test_GdipDrawCurve3(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurve3I(void) @@ -623,7 +626,7 @@ static void test_GdipDrawCurve3I(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPoint points[3]; points[0].X = 0; @@ -695,7 +698,7 @@ static void test_GdipDrawCurve3I(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurve2(void) @@ -703,7 +706,7 @@ static void test_GdipDrawCurve2(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPointF points[3]; points[0].X = 0; @@ -762,7 +765,7 @@ static void test_GdipDrawCurve2(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurve2I(void) @@ -770,7 +773,7 @@ static void test_GdipDrawCurve2I(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPoint points[3]; points[0].X = 0; @@ -829,7 +832,7 @@ static void test_GdipDrawCurve2I(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurve(void) @@ -837,7 +840,7 @@ static void test_GdipDrawCurve(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPointF points[3]; points[0].X = 0; @@ -890,7 +893,7 @@ static void test_GdipDrawCurve(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawCurveI(void) @@ -898,7 +901,7 @@ static void test_GdipDrawCurveI(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPoint points[3]; points[0].X = 0; @@ -951,7 +954,7 @@ static void test_GdipDrawCurveI(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawLineI(void) @@ -959,7 +962,7 @@ static void test_GdipDrawLineI(void) GpStatus status; GpGraphics *graphics = NULL; GpPen *pen = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* make a graphics object and pen object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -989,7 +992,7 @@ static void test_GdipDrawLineI(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawLinesI(void) @@ -998,7 +1001,7 @@ static void test_GdipDrawLinesI(void) GpGraphics *graphics = NULL; GpPen *pen = NULL; GpPoint *ptf = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* make a graphics object and pen object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -1041,7 +1044,7 @@ static void test_GdipDrawLinesI(void) GdipDeletePen(pen); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_Get_Release_DC(void) @@ -1051,7 +1054,7 @@ static void test_Get_Release_DC(void) GpPen *pen; GpSolidFill *brush; GpPath *path; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); HDC retdc; REAL r; CompositingQuality quality; @@ -1345,14 +1348,14 @@ static void test_Get_Release_DC(void) GdipDeleteMatrix(m); DeleteObject(hrgn); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_transformpoints(void) { GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpPointF ptf[2]; GpPoint pt[2]; @@ -1465,14 +1468,14 @@ static void test_transformpoints(void) expect(18, pt[1].Y); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_get_set_clip(void) { GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpRegion *clip; GpRectF rect; BOOL res; @@ -1544,14 +1547,14 @@ static void test_get_set_clip(void) GdipDeleteRegion(clip); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_isempty(void) { GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpRegion *clip; BOOL res; @@ -1578,7 +1581,7 @@ static void test_isempty(void) GdipDeleteRegion(clip); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_clear(void) @@ -1592,7 +1595,7 @@ static void test_clear(void) static void test_textcontrast(void) { GpStatus status; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpGraphics *graphics; UINT contrast; @@ -1608,7 +1611,7 @@ static void test_textcontrast(void) expect(4, contrast); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipDrawString(void) @@ -1620,7 +1623,7 @@ static void test_GdipDrawString(void) GpStringFormat *format; GpBrush *brush; LOGFONTA logfont; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); static const WCHAR string[] = {'T','e','s','t',0}; memset(&logfont,0,sizeof(logfont)); @@ -1658,7 +1661,7 @@ static void test_GdipDrawString(void) GdipDeleteFont(fnt); GdipDeleteStringFormat(format); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipGetVisibleClipBounds_screen(void) @@ -1758,36 +1761,10 @@ static void test_GdipGetVisibleClipBounds_window(void) GpGraphics *graphics = NULL; GpRectF rectf, window, exp, clipr; GpRect recti; - HWND hwnd; - WNDCLASSA class; HDC hdc; PAINTSTRUCT ps; - HINSTANCE hInstance = GetModuleHandle(NULL); RECT wnd_rect; - window.X = 0; - window.Y = 0; - window.Width = 200; - window.Height = 300; - - class.lpszClassName = "ClipBoundsTestClass"; - class.style = CS_HREDRAW | CS_VREDRAW; - class.lpfnWndProc = DefWindowProcA; - class.hInstance = hInstance; - class.hIcon = LoadIcon(0, IDI_APPLICATION); - class.hCursor = LoadCursor(NULL, IDC_ARROW); - class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - class.lpszMenuName = 0; - class.cbClsExtra = 0; - class.cbWndExtra = 0; - RegisterClass(&class); - - hwnd = CreateWindow(class.lpszClassName, "ClipboundsTest", - WS_OVERLAPPEDWINDOW, window.X, window.Y, window.Width, window.Height, - NULL, NULL, hInstance, NULL); - - ok(hwnd != NULL, "Expected window to be created\n"); - /* get client area size */ ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n"); window.X = wnd_rect.left; @@ -1870,7 +1847,6 @@ static void test_GdipGetVisibleClipBounds_window(void) GdipDeleteGraphics(graphics); EndPaint(hwnd, &ps); - DestroyWindow(hwnd); } static void test_GdipGetVisibleClipBounds(void) @@ -1878,7 +1854,7 @@ static void test_GdipGetVisibleClipBounds(void) GpGraphics* graphics = NULL; GpRectF rectf; GpRect rect; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); GpStatus status; status = GdipCreateFromHDC(hdc, &graphics); @@ -1899,7 +1875,7 @@ static void test_GdipGetVisibleClipBounds(void) expect(InvalidParameter, status); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); test_GdipGetVisibleClipBounds_screen(); test_GdipGetVisibleClipBounds_window(); @@ -1933,7 +1909,7 @@ static void test_GdipIsVisiblePoint(void) { GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); REAL x, y; BOOL val; @@ -2105,14 +2081,14 @@ static void test_GdipIsVisiblePoint(void) ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipIsVisibleRect(void) { GpStatus status; GpGraphics *graphics = NULL; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); REAL x, y, width, height; BOOL val; @@ -2267,7 +2243,7 @@ static void test_GdipIsVisibleRect(void) ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); GdipDeleteGraphics(graphics); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); } static void test_GdipGetNearestColor(void) @@ -2276,7 +2252,7 @@ static void test_GdipGetNearestColor(void) GpGraphics *graphics; GpBitmap *bitmap; ARGB color = 0xdeadbeef; - HDC hdc = GetDC(0); + HDC hdc = GetDC( hwnd ); /* create a graphics object */ ok(hdc != NULL, "Expected HDC to be initialized\n"); @@ -2415,17 +2391,269 @@ static void test_GdipGetNearestColor(void) expect(Ok, status); status = GdipGetNearestColor(graphics, &color); expect(Ok, status); - todo_wine expect(0xffa8b8e8, color); + todo_wine + ok(color == 0xffa8b8e8 || + broken(color == 0xffa0b8e0), /* Win98/WinMe */ + "Expected ffa8b8e8, got %.8x\n", color); GdipDeleteGraphics(graphics); GdipDisposeImage((GpImage*)bitmap); - ReleaseDC(0, hdc); + ReleaseDC(hwnd, hdc); +} + +static void test_string_functions(void) +{ + GpStatus status; + GpGraphics *graphics; + GpFontFamily *family; + GpFont *font; + RectF rc, char_bounds, bounds; + GpBrush *brush; + ARGB color = 0xff000000; + HDC hdc = GetDC( hwnd ); + const WCHAR fontname[] = {'C','o','u','r','i','e','r',' ','N','e','w',0}; + const WCHAR fontname2[] = {'C','o','u','r','i','e','r',0}; + const WCHAR teststring[] = {'o','o',' ','o','\n','o',0}; + REAL char_width, char_height; + INT codepointsfitted, linesfilled; + GpStringFormat *format; + CharacterRange ranges[3] = {{0, 1}, {1, 3}, {5, 1}}; + GpRegion *regions[4] = {0}; + BOOL region_isempty[4]; + int i; + + ok(hdc != NULL, "Expected HDC to be initialized\n"); + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + ok(graphics != NULL, "Expected graphics to be initialized\n"); + + status = GdipCreateFontFamilyFromName(fontname, NULL, &family); + + if (status != Ok) + { + /* Wine doesn't have Courier New? */ + todo_wine expect(Ok, status); + status = GdipCreateFontFamilyFromName(fontname2, NULL, &family); + } + + expect(Ok, status); + + status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font); + expect(Ok, status); + + status = GdipCreateSolidFill(color, (GpSolidFill**)&brush); + expect(Ok, status); + + status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format); + expect(Ok, status); + + rc.X = 0; + rc.Y = 0; + rc.Width = 100.0; + rc.Height = 100.0; + + status = GdipDrawString(NULL, teststring, 6, font, &rc, NULL, brush); + expect(InvalidParameter, status); + + status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush); + expect(InvalidParameter, status); + + status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush); + expect(InvalidParameter, status); + + status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush); + expect(InvalidParameter, status); + + status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL); + expect(InvalidParameter, status); + + status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, brush); + expect(Ok, status); + + status = GdipMeasureString(NULL, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(InvalidParameter, status); + + status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(InvalidParameter, status); + + status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(InvalidParameter, status); + + status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(InvalidParameter, status); + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled); + expect(InvalidParameter, status); + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, NULL, &linesfilled); + expect(Ok, status); + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, NULL); + expect(Ok, status); + + status = GdipMeasureString(graphics, teststring, 1, font, &rc, NULL, &char_bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, char_bounds.X); + expectf(0.0, char_bounds.Y); + ok(char_bounds.Width > 0, "got %0.2f\n", bounds.Width); + ok(char_bounds.Height > 0, "got %0.2f\n", bounds.Height); + expect(1, codepointsfitted); + expect(1, linesfilled); + + status = GdipMeasureString(graphics, teststring, 2, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + ok(bounds.Width > char_bounds.Width, "got %0.2f, expected at least %0.2f\n", bounds.Width, char_bounds.Width); + expectf(char_bounds.Height, bounds.Height); + expect(2, codepointsfitted); + expect(1, linesfilled); + char_width = bounds.Width - char_bounds.Width; + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + expectf_(char_bounds.Width + char_width * 3, bounds.Width, 0.01); + ok(bounds.Height > char_bounds.Height, "got %0.2f, expected at least %0.2f\n", bounds.Height, char_bounds.Height); + expect(6, codepointsfitted); + expect(2, linesfilled); + char_height = bounds.Height - char_bounds.Height; + + /* Cut off everything after the first space. */ + rc.Width = char_bounds.Width + char_width * 2.5; + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + expectf_(char_bounds.Width + char_width, bounds.Width, 0.01); + expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01); + expect(6, codepointsfitted); + expect(3, linesfilled); + + /* Cut off everything including the first space. */ + rc.Width = char_bounds.Width + char_width * 1.5; + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + expectf_(char_bounds.Width + char_width, bounds.Width, 0.01); + expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01); + expect(6, codepointsfitted); + expect(3, linesfilled); + + /* Cut off everything after the first character. */ + rc.Width = char_bounds.Width + char_width * 0.5; + + status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + expectf_(char_bounds.Width, bounds.Width, 0.01); + todo_wine expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05); + expect(6, codepointsfitted); + todo_wine expect(4, linesfilled); + + status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges); + expect(Ok, status); + + rc.Width = 100.0; + + for (i=0; i<4; i++) + { + status = GdipCreateRegion(®ions[i]); + expect(Ok, status); + } + + status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions); + expect(InvalidParameter, status); + + status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions); + expect(InvalidParameter, status); + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions); + expect(InvalidParameter, status); + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions); + expect(InvalidParameter, status); + + if (0) + { + /* Crashes on Windows XP */ + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions); + expect(InvalidParameter, status); + } + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL); + expect(InvalidParameter, status); + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions); + expect(InvalidParameter, status); + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions); + expect(Ok, status); + + for (i=0; i<4; i++) + { + status = GdipIsEmptyRegion(regions[i], graphics, ®ion_isempty[i]); + expect(Ok, status); + } + + ok(!region_isempty[0], "region shouldn't be empty\n"); + ok(!region_isempty[1], "region shouldn't be empty\n"); + ok(!region_isempty[2], "region shouldn't be empty\n"); + ok(!region_isempty[3], "region shouldn't be empty\n"); + + /* Cut off everything after the first space, and the second line. */ + rc.Width = char_bounds.Width + char_width * 2.5; + rc.Height = char_bounds.Height + char_height * 0.5; + + status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions); + expect(Ok, status); + + for (i=0; i<4; i++) + { + status = GdipIsEmptyRegion(regions[i], graphics, ®ion_isempty[i]); + expect(Ok, status); + } + + ok(!region_isempty[0], "region shouldn't be empty\n"); + ok(!region_isempty[1], "region shouldn't be empty\n"); + ok(region_isempty[2], "region should be empty\n"); + ok(!region_isempty[3], "region shouldn't be empty\n"); + + for (i=0; i<4; i++) + GdipDeleteRegion(regions[i]); + + GdipDeleteStringFormat(format); + GdipDeleteBrush(brush); + GdipDeleteFont(font); + GdipDeleteFontFamily(family); + GdipDeleteGraphics(graphics); + + ReleaseDC(hwnd, hdc); } START_TEST(graphics) { struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; + WNDCLASSA class; + + memset( &class, 0, sizeof(class) ); + class.lpszClassName = "gdiplus_test"; + class.style = CS_HREDRAW | CS_VREDRAW; + class.lpfnWndProc = DefWindowProcA; + class.hInstance = GetModuleHandleA(0); + class.hIcon = LoadIcon(0, IDI_APPLICATION); + class.hCursor = LoadCursor(NULL, IDC_ARROW); + class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + RegisterClassA( &class ); + hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 ); + ok(hwnd != NULL, "Expected window to be created\n"); gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; @@ -2460,6 +2688,8 @@ START_TEST(graphics) test_clear(); test_textcontrast(); test_fromMemoryBitmap(); + test_string_functions(); GdiplusShutdown(gdiplusToken); + DestroyWindow( hwnd ); } diff --git a/rostests/winetests/gdiplus/image.c b/rostests/winetests/gdiplus/image.c index 9085ef2cf2d..74e6ee1db23 100644 --- a/rostests/winetests/gdiplus/image.c +++ b/rostests/winetests/gdiplus/image.c @@ -226,10 +226,23 @@ static void test_GdipImageGetFrameDimensionsCount(void) stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0); expect(InvalidParameter, stat); + stat = GdipImageGetFrameCount(NULL, &dimension, &count); + expect(InvalidParameter, stat); + + /* WinXP crashes on this test */ + if(0) + { + stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL); + expect(InvalidParameter, stat); + } + + stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count); + expect(Ok, stat); + count = 12345; stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count); - todo_wine expect(Ok, stat); - todo_wine expect(1, count); + expect(Ok, stat); + expect(1, count); GdipBitmapSetPixel(bm, 0, 0, 0xffffffff); @@ -793,6 +806,26 @@ static const unsigned char jpgimage[285] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01, 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9 }; +/* 1x1 pixel tiff */ +static const unsigned char tiffimage[] = { +0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00, +0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00, +0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00, +0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01, +0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00, +0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00, +0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01, +0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00, +0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00, +0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01, +0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00, +0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00, +0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65, +0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74, +0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48, +0x00,0x00,0x00,0x01 +}; /* 320x320 twip wmf */ static const unsigned char wmfimage[180] = { 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05, @@ -814,6 +847,7 @@ static void test_getrawformat(void) test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE); test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE); test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE); + test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE); test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE); } @@ -828,6 +862,7 @@ static void test_loadwmf(void) GpRectF bounds; GpUnit unit; REAL res = 12345.0; + MetafileHeader header; hglob = GlobalAlloc (0, sizeof(wmfimage)); data = GlobalLock (hglob); @@ -863,6 +898,27 @@ static void test_loadwmf(void) expect(Ok, stat); todo_wine expectf(1440.0, res); + memset(&header, 0, sizeof(header)); + stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header); + expect(Ok, stat); + if (stat == Ok) + { + todo_wine expect(MetafileTypeWmfPlaceable, header.Type); + todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size); + todo_wine expect(0x300, header.Version); + expect(0, header.EmfPlusFlags); + todo_wine expectf(1440.0, header.DpiX); + todo_wine expectf(1440.0, header.DpiY); + expect(0, header.X); + expect(0, header.Y); + todo_wine expect(320, header.Width); + todo_wine expect(320, header.Height); + todo_wine expect(1, U(header).WmfHeader.mtType); + expect(0, header.EmfPlusHeaderSize); + expect(0, header.LogicalDpiX); + expect(0, header.LogicalDpiY); + } + GdipDisposeImage(img); } @@ -874,6 +930,7 @@ static void test_createfromwmf(void) GpRectF bounds; GpUnit unit; REAL res = 12345.0; + MetafileHeader header; hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), wmfimage+sizeof(WmfPlaceableFileHeader)); @@ -885,11 +942,11 @@ static void test_createfromwmf(void) stat = GdipGetImageBounds(img, &bounds, &unit); expect(Ok, stat); - todo_wine expect(UnitPixel, unit); + expect(UnitPixel, unit); expectf(0.0, bounds.X); expectf(0.0, bounds.Y); - todo_wine expectf(320.0, bounds.Width); - todo_wine expectf(320.0, bounds.Height); + expectf(320.0, bounds.Width); + expectf(320.0, bounds.Height); stat = GdipGetImageHorizontalResolution(img, &res); expect(Ok, stat); @@ -899,6 +956,27 @@ static void test_createfromwmf(void) expect(Ok, stat); expectf(1440.0, res); + memset(&header, 0, sizeof(header)); + stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header); + expect(Ok, stat); + if (stat == Ok) + { + todo_wine expect(MetafileTypeWmfPlaceable, header.Type); + todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size); + todo_wine expect(0x300, header.Version); + expect(0, header.EmfPlusFlags); + todo_wine expectf(1440.0, header.DpiX); + todo_wine expectf(1440.0, header.DpiY); + expect(0, header.X); + expect(0, header.Y); + todo_wine expect(320, header.Width); + todo_wine expect(320, header.Height); + todo_wine expect(1, U(header).WmfHeader.mtType); + expect(0, header.EmfPlusHeaderSize); + expect(0, header.LogicalDpiX); + expect(0, header.LogicalDpiY); + } + GdipDisposeImage(img); } @@ -1544,7 +1622,7 @@ static void test_multiframegif(void) count = 12345; stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); - todo_wine expect(Ok, stat); + expect(Ok, stat); todo_wine expect(2, count); /* SelectActiveFrame overwrites our current data */ @@ -1618,8 +1696,8 @@ static void test_multiframegif(void) count = 12345; stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); - todo_wine expect(Ok, stat); - todo_wine expect(1, count); + expect(Ok, stat); + expect(1, count); GdipDisposeImage((GpImage*)bmp); IStream_Release(stream); @@ -1641,30 +1719,30 @@ static void test_rotateflip(void) expect(Ok, stat); stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone); - todo_wine expect(Ok, stat); + expect(Ok, stat); stat = GdipGetImageWidth(bitmap, &width); expect(Ok, stat); stat = GdipGetImageHeight(bitmap, &height); expect(Ok, stat); - todo_wine expect(2, width); - todo_wine expect(3, height); + expect(2, width); + expect(3, height); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); expect(Ok, stat); - todo_wine expect(0xff00ffff, color); + expect(0xff00ffff, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color); expect(Ok, stat); - todo_wine expect(0xffff0000, color); + expect(0xffff0000, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color); - todo_wine expect(Ok, stat); - todo_wine expect(0xffffff00, color); + expect(Ok, stat); + expect(0xffffff00, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color); - todo_wine expect(Ok, stat); - todo_wine expect(0xff0000ff, color); + expect(Ok, stat); + expect(0xff0000ff, color); expect(0, bits[0]); expect(0, bits[1]); @@ -1677,7 +1755,7 @@ static void test_rotateflip(void) expect(Ok, stat); stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX); - todo_wine expect(Ok, stat); + expect(Ok, stat); stat = GdipGetImageWidth(bitmap, &width); expect(Ok, stat); @@ -1688,19 +1766,19 @@ static void test_rotateflip(void) stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); expect(Ok, stat); - todo_wine expect(0xff0000ff, color); + expect(0xff0000ff, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color); expect(Ok, stat); - todo_wine expect(0xffff0000, color); + expect(0xffff0000, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color); expect(Ok, stat); - todo_wine expect(0xffffff00, color); + expect(0xffffff00, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color); expect(Ok, stat); - todo_wine expect(0xff00ffff, color); + expect(0xff00ffff, color); expect(0, bits[0]); expect(0, bits[1]); @@ -1713,7 +1791,7 @@ static void test_rotateflip(void) expect(Ok, stat); stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY); - todo_wine expect(Ok, stat); + expect(Ok, stat); stat = GdipGetImageWidth(bitmap, &width); expect(Ok, stat); @@ -1724,19 +1802,19 @@ static void test_rotateflip(void) stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); expect(Ok, stat); - todo_wine expect(0xff00ffff, color); + expect(0xff00ffff, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color); expect(Ok, stat); - todo_wine expect(0xffffff00, color); + expect(0xffffff00, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color); expect(Ok, stat); - todo_wine expect(0xffff0000, color); + expect(0xffff0000, color); stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color); expect(Ok, stat); - todo_wine expect(0xff0000ff, color); + expect(0xff0000ff, color); expect(0, bits[0]); expect(0, bits[1]); @@ -1801,7 +1879,7 @@ static void test_remaptable(void) stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); expect(Ok, stat); - todo_wine ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color); + ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color); GdipDeleteGraphics(graphics); GdipDisposeImage((GpImage*)bitmap1); diff --git a/rostests/winetests/inetcomm/mimeintl.c b/rostests/winetests/inetcomm/mimeintl.c index 563943f663b..f64d7d93d23 100644 --- a/rostests/winetests/inetcomm/mimeintl.c +++ b/rostests/winetests/inetcomm/mimeintl.c @@ -156,7 +156,7 @@ static void test_charset(void) hr = MimeOleGetInternat(&internat); ok(hr == S_OK, "ret %08x\n", hr); - hr = IMimeInternational_FindCharset(internat, "non-existent", &hcs); + hr = IMimeInternational_FindCharset(internat, "nonexistent", &hcs); ok(hr == MIME_E_NOT_FOUND, "got %08x\n", hr); hr = IMimeInternational_FindCharset(internat, "windows-1252", &hcs_windows_1252); diff --git a/rostests/winetests/jscript/regexp.js b/rostests/winetests/jscript/regexp.js index fac111227fe..7b74cb11421 100644 --- a/rostests/winetests/jscript/regexp.js +++ b/rostests/winetests/jscript/regexp.js @@ -113,6 +113,7 @@ ok(typeof(m) === "object", "typeof m is not object"); ok(m.length === 2, "m.length is not 2"); ok(m["0"] === "ab", "m[0] is not \"ab\""); ok(m["1"] === "ab", "m[1] is not \"ab\""); +/* ok(m.input === "abcabc", "m.input = " + m.input); */ m = "abcabc".match(/Ab/g); ok(typeof(m) === "object", "typeof m is not object"); @@ -167,6 +168,32 @@ ok(m["0"] === "ab", "m[0] is not \"ab\""); m = "abcabc".match(); ok(m === null, "m is not null"); +m = "abcabc".match(/(a)(b)cabc/); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 3, "m.length is not 3"); +ok(m[0] === "abcabc", "m[0] is not \"abc\""); +ok(m[1] === "a", "m[1] is not \"a\""); +ok(m[2] === "b", "m[2] is not \"b\""); + +re = /(a)bcabc/; +re.lastIndex = -3; +m = "abcabc".match(re); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 2, "m.length = " + m.length + "expected 3"); +ok(m[0] === "abcabc", "m[0] is not \"abc\""); +ok(m[1] === "a", "m[1] is not \"a\""); +ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex); + +re = /(a)bcabc/; +re.lastIndex = 2; +m = "abcabcxxx".match(re); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 2, "m.length = " + m.length + "expected 3"); +ok(m[0] === "abcabc", "m[0] is not \"abc\""); +ok(m[1] === "a", "m[1] is not \"a\""); +ok(m.input === "abcabcxxx", "m.input = " + m.input); +ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex); + r = "- [test] -".replace(re = /\[([^\[]+)\]/g, "success"); ok(r === "- success -", "r = " + r + " expected '- success -'"); ok(re.lastIndex === 8, "re.lastIndex = " + re.lastIndex); @@ -410,6 +437,19 @@ m = re.exec(" "); ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0"); ok(m === null, "m = " + m + " expected null"); +re = /a/; +re.lastIndex = -3; +ok(re.lastIndex === -3, "re.lastIndex = " + re.lastIndex + " expected -3"); +m = re.exec(" a a "); +ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 0"); +ok(m.index === 1, "m = " + m + " expected 1"); + +re.lastIndex = -1; +ok(re.lastIndex === -1, "re.lastIndex = " + re.lastIndex + " expected -1"); +m = re.exec(" "); +ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0"); +ok(m === null, "m = " + m + " expected null"); + re = /aa/g; i = 'baacd'.search(re); ok(i === 1, "'baacd'.search(re) = " + i); diff --git a/rostests/winetests/msctf/inputprocessor.c b/rostests/winetests/msctf/inputprocessor.c index 7ba9140573a..c445b41b01e 100644 --- a/rostests/winetests/msctf/inputprocessor.c +++ b/rostests/winetests/msctf/inputprocessor.c @@ -38,15 +38,28 @@ static ITfDocumentMgr *g_dm = NULL; static TfClientId cid = 0; static TfClientId tid = 0; +static ITextStoreACPSink *ACPSink; + #define SINK_UNEXPECTED 0 #define SINK_EXPECTED 1 #define SINK_FIRED 2 +#define SINK_IGNORE 3 +#define SINK_OPTIONAL 4 + +#define SINK_ACTION_MASK 0xff +#define SINK_OPTION_MASK 0xff00 +#define SINK_EXPECTED_COUNT_MASK 0xff0000 + +#define SINK_OPTION_TODO 0x0100 + +#define FOCUS_IGNORE (ITfDocumentMgr*)0xffffffff static BOOL test_ShouldActivate = FALSE; static BOOL test_ShouldDeactivate = FALSE; static DWORD tmSinkCookie; static DWORD tmSinkRefCount; +static DWORD documentStatus; static ITfDocumentMgr *test_CurrentFocus = NULL; static ITfDocumentMgr *test_PrevFocus = NULL; static INT test_OnSetFocus = SINK_UNEXPECTED; @@ -54,236 +67,103 @@ static INT test_OnInitDocumentMgr = SINK_UNEXPECTED; static INT test_OnPushContext = SINK_UNEXPECTED; static INT test_OnPopContext = SINK_UNEXPECTED; static INT test_KEV_OnSetFocus = SINK_UNEXPECTED; +static INT test_ACP_AdviseSink = SINK_UNEXPECTED; +static INT test_ACP_GetStatus = SINK_UNEXPECTED; +static INT test_ACP_RequestLock = SINK_UNEXPECTED; +static INT test_ACP_GetEndACP = SINK_UNEXPECTED; +static INT test_ACP_GetSelection = SINK_UNEXPECTED; +static INT test_DoEditSession = SINK_UNEXPECTED; +static INT test_ACP_InsertTextAtSelection = SINK_UNEXPECTED; +static INT test_ACP_SetSelection = SINK_UNEXPECTED; +static INT test_OnEndEdit = SINK_UNEXPECTED; -HRESULT RegisterTextService(REFCLSID rclsid); -HRESULT UnregisterTextService(); -HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut); -HRESULT TextStoreACP_Constructor(IUnknown **ppOut); - -DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3); -DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed); -DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); -DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31); -DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14); -DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43); -DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B); -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); -DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50); -DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72); - - -static HRESULT initialize(void) -{ - HRESULT hr; - CoInitialize(NULL); - hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp); - if (SUCCEEDED(hr)) - hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm); - if (SUCCEEDED(hr)) - hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL, - CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm); - return hr; -} - -static void cleanup(void) -{ - if (g_ipp) - ITfInputProcessorProfiles_Release(g_ipp); - if (g_cm) - ITfCategoryMgr_Release(g_cm); - if (g_tm) - ITfThreadMgr_Release(g_tm); - CoUninitialize(); -} - -static void test_Register(void) -{ - HRESULT hr; - - static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0}; - static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0}; - - hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid); - ok(SUCCEEDED(hr),"Unable to get current language id\n"); - trace("Current Language %x\n",gLangid); - - hr = RegisterTextService(&CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to register COM for TextService\n"); - hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr); - hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1); - ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr); -} -static void test_Unregister(void) +static inline int expected_count(int *sink) { - HRESULT hr; - hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService); - ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr); - UnregisterTextService(); + return (*sink & SINK_EXPECTED_COUNT_MASK)>>16; } -static void test_EnumInputProcessorInfo(void) +static inline void _sink_fire_ok(INT *sink, const CHAR* name) { - IEnumGUID *ppEnum; - BOOL found = FALSE; + int count; + int todo = *sink & SINK_OPTION_TODO; + int action = *sink & SINK_ACTION_MASK; - if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum))) - { - ULONG fetched; - GUID g; - while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK) - { - if(IsEqualGUID(&g,&CLSID_FakeService)) - found = TRUE; - } - } - ok(found,"Did not find registered text service\n"); -} + if (winetest_interactive) + winetest_trace("firing %s\n",name); -static void test_EnumLanguageProfiles(void) -{ - BOOL found = FALSE; - IEnumTfLanguageProfiles *ppEnum; - if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum))) + switch (action) { - TF_LANGUAGEPROFILE profile; - while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK) - { - if (IsEqualGUID(&profile.clsid,&CLSID_FakeService)) + case SINK_OPTIONAL: + case SINK_EXPECTED: + count = expected_count(sink); + if (count > 1) { - found = TRUE; - ok(profile.langid == gLangid, "LangId Incorrect\n"); - ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n"); - ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n"); + count --; + *sink = (*sink & ~SINK_EXPECTED_COUNT_MASK) + (count << 16); + return; } - } + break; + case SINK_IGNORE: + winetest_trace("Ignoring %s\n",name); + return; + default: + if (todo) + todo_wine winetest_ok(0, "Unexpected %s sink\n",name); + else + winetest_ok(0, "Unexpected %s sink\n",name); } - ok(found,"Registered text service not found\n"); -} - -static void test_RegisterCategory(void) -{ - HRESULT hr; - hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); - hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); -} - -static void test_UnregisterCategory(void) -{ - HRESULT hr; - hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); - hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); - ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); -} - -static void test_FindClosestCategory(void) -{ - GUID output; - HRESULT hr; - const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING}; - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n"); - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n"); - - hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3); - ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); - ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n"); -} - -static void test_Enable(void) -{ - HRESULT hr; - BOOL enabled = FALSE; - - hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE); - ok(SUCCEEDED(hr),"Failed to enable text service\n"); - hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled); - ok(SUCCEEDED(hr),"Failed to get enabled state\n"); - ok(enabled == TRUE,"enabled state incorrect\n"); + *sink = SINK_FIRED; } -static void test_Disable(void) -{ - HRESULT hr; - - trace("Disabling\n"); - hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE); - ok(SUCCEEDED(hr),"Failed to disable text service\n"); -} +#define sink_fire_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_fire_ok(a,b) -static void test_ThreadMgrAdviseSinks(void) +static inline void _sink_check_ok(INT *sink, const CHAR* name) { - ITfSource *source = NULL; - HRESULT hr; - IUnknown *sink; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); - ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); - if (!source) - return; - - ThreadMgrEventSink_Constructor(&sink); - - tmSinkRefCount = 1; - tmSinkCookie = 0; - hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to Advise Sink\n"); - ok(tmSinkCookie!=0,"Failed to get sink cookie\n"); + int action = *sink & SINK_ACTION_MASK; + int todo = *sink & SINK_OPTION_TODO; - /* Advising the sink adds a ref, Relesing here lets the object be deleted - when unadvised */ - tmSinkRefCount = 2; - IUnknown_Release(sink); - ITfSource_Release(source); + switch (action) + { + case SINK_OPTIONAL: + if (winetest_interactive) + winetest_trace("optional sink %s not fired\n",name); + case SINK_FIRED: + break; + case SINK_IGNORE: + return; + default: + if (todo) + todo_wine winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink); + else + winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink); + } + *sink = SINK_UNEXPECTED; } -static void test_ThreadMgrUnadviseSinks(void) -{ - ITfSource *source = NULL; - HRESULT hr; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); - ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); - if (!source) - return; - - tmSinkRefCount = 1; - hr = ITfSource_UnadviseSink(source, tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); - ITfSource_Release(source); -} +#define sink_check_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_check_ok(a,b) /********************************************************************** - * ITfKeyEventSink + * ITextStoreACP **********************************************************************/ -typedef struct tagKeyEventSink +typedef struct tagTextStoreACP { - const ITfKeyEventSinkVtbl *KeyEventSinkVtbl; + const ITextStoreACPVtbl *TextStoreACPVtbl; LONG refCount; -} KeyEventSink; -static void KeyEventSink_Destructor(KeyEventSink *This) +} TextStoreACP; + +static void TextStoreACP_Destructor(TextStoreACP *This) { HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut) +static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; *ppvOut = NULL; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink)) + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP)) { *ppvOut = This; } @@ -297,718 +177,1097 @@ static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID return E_NOINTERFACE; } -static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface) +static ULONG WINAPI TextStoreACP_AddRef(ITextStoreACP *iface) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface) +static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface) { - KeyEventSink *This = (KeyEventSink *)iface; + TextStoreACP *This = (TextStoreACP *)iface; ULONG ret; ret = InterlockedDecrement(&This->refCount); if (ret == 0) - KeyEventSink_Destructor(This); + TextStoreACP_Destructor(This); return ret; } -static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface, - BOOL fForeground) +static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface, + REFIID riid, IUnknown *punk, DWORD dwMask) { - ok(test_KEV_OnSetFocus == SINK_EXPECTED,"Unexpected KeyEventSink_OnSetFocus\n"); - test_KEV_OnSetFocus = SINK_FIRED; + HRESULT hr; + + sink_fire_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink"); + + hr = IUnknown_QueryInterface(punk, &IID_ITextStoreACPSink,(LPVOID*)(&ACPSink)); + ok(SUCCEEDED(hr),"Unable to QueryInterface on sink\n"); return S_OK; } -static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface, + IUnknown *punk) { trace("\n"); return S_OK; } -static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface, + DWORD dwLockFlags, HRESULT *phrSession) { - trace("\n"); + sink_fire_ok(&test_ACP_RequestLock,"TextStoreACP_RequestLock"); + *phrSession = ITextStoreACPSink_OnLockGranted(ACPSink, dwLockFlags); return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface, + TS_STATUS *pdcs) { - trace("\n"); + sink_fire_ok(&test_ACP_GetStatus,"TextStoreACP_GetStatus"); + pdcs->dwDynamicFlags = documentStatus; return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface, - ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface, + LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, + LONG *pacpResultEnd) { trace("\n"); return S_OK; } - -static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface, - ITfContext *pic, REFGUID rguid, BOOL *pfEaten) +static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface, + ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) { - trace("\n"); + sink_fire_ok(&test_ACP_GetSelection,"TextStoreACP_GetSelection"); + + pSelection->acpStart = 10; + pSelection->acpEnd = 20; + pSelection->style.fInterimChar = 0; + pSelection->style.ase = TS_AE_NONE; + *pcFetched = 1; + return S_OK; } - -static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl = +static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface, + ULONG ulCount, const TS_SELECTION_ACP *pSelection) { - KeyEventSink_QueryInterface, - KeyEventSink_AddRef, - KeyEventSink_Release, + sink_fire_ok(&test_ACP_SetSelection,"TextStoreACP_SetSelection"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface, + LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, + ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, + ULONG *pcRunInfoRet, LONG *pacpNext) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_SetText(ITextStoreACP *iface, + DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, + ULONG cch, TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetFormattedText(ITextStoreACP *iface, + LONG acpStart, LONG acpEnd, IDataObject **ppDataObject) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetEmbedded(ITextStoreACP *iface, + LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_QueryInsertEmbedded(ITextStoreACP *iface, + const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertEmbedded(ITextStoreACP *iface, + DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, + TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface, + DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, + LONG *pacpEnd, TS_TEXTCHANGE *pChange) +{ + sink_fire_ok(&test_ACP_InsertTextAtSelection,"TextStoreACP_InsertTextAtSelection"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface, + DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, + TS_TEXTCHANGE *pChange) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestSupportedAttrs(ITextStoreACP *iface, + DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestAttrsAtPosition(ITextStoreACP *iface, + LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RequestAttrsTransitioningAtPosition(ITextStoreACP *iface, + LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_FindNextAttrTransition(ITextStoreACP *iface, + LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, + DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface, + ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface, + LONG *pacp) +{ + sink_fire_ok(&test_ACP_GetEndACP,"TextStoreACP_GetEndACP"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface, + TsViewCookie *pvcView) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetACPFromPoint(ITextStoreACP *iface, + TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, + LONG *pacp) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetTextExt(ITextStoreACP *iface, + TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, + BOOL *pfClipped) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetScreenExt(ITextStoreACP *iface, + TsViewCookie vcView, RECT *prc) +{ + trace("\n"); + return S_OK; +} +static HRESULT WINAPI TextStoreACP_GetWnd(ITextStoreACP *iface, + TsViewCookie vcView, HWND *phwnd) +{ + trace("\n"); + return S_OK; +} - KeyEventSink_OnSetFocus, - KeyEventSink_OnTestKeyDown, - KeyEventSink_OnTestKeyUp, - KeyEventSink_OnKeyDown, - KeyEventSink_OnKeyUp, - KeyEventSink_OnPreservedKey +static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl = +{ + TextStoreACP_QueryInterface, + TextStoreACP_AddRef, + TextStoreACP_Release, + + TextStoreACP_AdviseSink, + TextStoreACP_UnadviseSink, + TextStoreACP_RequestLock, + TextStoreACP_GetStatus, + TextStoreACP_QueryInsert, + TextStoreACP_GetSelection, + TextStoreACP_SetSelection, + TextStoreACP_GetText, + TextStoreACP_SetText, + TextStoreACP_GetFormattedText, + TextStoreACP_GetEmbedded, + TextStoreACP_QueryInsertEmbedded, + TextStoreACP_InsertEmbedded, + TextStoreACP_InsertTextAtSelection, + TextStoreACP_InsertEmbeddedAtSelection, + TextStoreACP_RequestSupportedAttrs, + TextStoreACP_RequestAttrsAtPosition, + TextStoreACP_RequestAttrsTransitioningAtPosition, + TextStoreACP_FindNextAttrTransition, + TextStoreACP_RetrieveRequestedAttrs, + TextStoreACP_GetEndACP, + TextStoreACP_GetActiveView, + TextStoreACP_GetACPFromPoint, + TextStoreACP_GetTextExt, + TextStoreACP_GetScreenExt, + TextStoreACP_GetWnd }; -HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut) +static HRESULT TextStoreACP_Constructor(IUnknown **ppOut) { - KeyEventSink *This; + TextStoreACP *This; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink)); + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACP)); if (This == NULL) return E_OUTOFMEMORY; - This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl; + This->TextStoreACPVtbl = &TextStoreACP_TextStoreACPVtbl; This->refCount = 1; - *ppOut = (ITfKeyEventSink*)This; + *ppOut = (IUnknown *)This; return S_OK; } - -static void test_KeystrokeMgr(void) +/********************************************************************** + * ITfThreadMgrEventSink + **********************************************************************/ +typedef struct tagThreadMgrEventSink { - ITfKeystrokeMgr *keymgr= NULL; - HRESULT hr; - TF_PRESERVEDKEY tfpk; - BOOL preserved; - ITfKeyEventSink *sink; - - KeyEventSink_Constructor(&sink); - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr); - ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n"); - - tfpk.uVKey = 'A'; - tfpk.uModifiers = TF_MOD_SHIFT; - - test_KEV_OnSetFocus = SINK_EXPECTED; - hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); - todo_wine ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n"); - - hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; + LONG refCount; +} ThreadMgrEventSink; - hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); +static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This) +{ + HeapFree(GetProcessHeap(),0,This); +} - hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); +static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) +{ + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + *ppvOut = NULL; - preserved = FALSE; - hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); - ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); - if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n"); + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink)) + { + *ppvOut = This; + } - hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); - ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } - hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); - ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n"); - if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n"); + return E_NOINTERFACE; +} - hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); - ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n"); +static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface) +{ + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + return InterlockedIncrement(&This->refCount); +} - hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n"); +static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface) +{ + ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + ULONG ret; - ITfKeystrokeMgr_Release(keymgr); - ITfKeyEventSink_Release(sink); + ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + ThreadMgrEventSink_Destructor(This); + return ret; } -static void test_Activate(void) +static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdim) { - HRESULT hr; + sink_fire_ok(&test_OnInitDocumentMgr,"ThreadMgrEventSink_OnInitDocumentMgr"); + return S_OK; +} - hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService); - ok(SUCCEEDED(hr),"Failed to Activate text service\n"); +static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdim) +{ + trace("\n"); + return S_OK; } -static inline int check_context_refcount(ITfContext *iface) +static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface, +ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) { - IUnknown_AddRef(iface); - return IUnknown_Release(iface); + sink_fire_ok(&test_OnSetFocus,"ThreadMgrEventSink_OnSetFocus"); + if (test_CurrentFocus != FOCUS_IGNORE) + ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n"); + if (test_PrevFocus != FOCUS_IGNORE) + ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n"); + return S_OK; } -static void test_startSession(void) +static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface, +ITfContext *pic) { HRESULT hr; - DWORD cnt; - DWORD editCookie; - ITfDocumentMgr *dmtest; - ITfContext *cxt,*cxt2,*cxt3,*cxtTest; - ITextStoreACP *ts; - TfClientId cid2 = 0; - - hr = ITfThreadMgr_Deactivate(g_tm); - ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n"); - - test_ShouldActivate = TRUE; - hr = ITfThreadMgr_Activate(g_tm,&cid); - ok(SUCCEEDED(hr),"Failed to Activate\n"); - ok(cid != tid,"TextService id mistakenly matches Client id\n"); - - test_ShouldActivate = FALSE; - hr = ITfThreadMgr_Activate(g_tm,&cid2); - ok(SUCCEEDED(hr),"Failed to Activate\n"); - ok (cid == cid2, "Second activate client ID does not match\n"); - - hr = ITfThreadMgr_Deactivate(g_tm); - ok(SUCCEEDED(hr),"Failed to Deactivate\n"); + ITfDocumentMgr *docmgr; + ITfContext *test; + + hr = ITfContext_GetDocumentMgr(pic,&docmgr); + ok(SUCCEEDED(hr),"GetDocumenMgr failed\n"); + test = (ITfContext*)0xdeadbeef; + ITfDocumentMgr_Release(docmgr); + hr = ITfDocumentMgr_GetTop(docmgr,&test); + ok(SUCCEEDED(hr),"GetTop failed\n"); + ok(test == pic, "Wrong context is on top\n"); + if (test) + ITfContext_Release(test); + + sink_fire_ok(&test_OnPushContext,"ThreadMgrEventSink_OnPushContext"); + return S_OK; +} - hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm); - ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); +static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface, +ITfContext *pic) +{ + HRESULT hr; + ITfDocumentMgr *docmgr; + ITfContext *test; + + hr = ITfContext_GetDocumentMgr(pic,&docmgr); + ok(SUCCEEDED(hr),"GetDocumenMgr failed\n"); + ITfDocumentMgr_Release(docmgr); + test = (ITfContext*)0xdeadbeef; + hr = ITfDocumentMgr_GetTop(docmgr,&test); + ok(SUCCEEDED(hr),"GetTop failed\n"); + ok(test == pic, "Wrong context is on top\n"); + if (test) + ITfContext_Release(test); + + sink_fire_ok(&test_OnPopContext,"ThreadMgrEventSink_OnPopContext"); + return S_OK; +} - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(dmtest == NULL,"Initial focus not null\n"); +static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl = +{ + ThreadMgrEventSink_QueryInterface, + ThreadMgrEventSink_AddRef, + ThreadMgrEventSink_Release, - test_CurrentFocus = g_dm; - test_PrevFocus = NULL; - test_OnSetFocus = SINK_EXPECTED; - hr = ITfThreadMgr_SetFocus(g_tm,g_dm); - ok(SUCCEEDED(hr),"SetFocus Failed\n"); - ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); - test_OnSetFocus = SINK_UNEXPECTED; + ThreadMgrEventSink_OnInitDocumentMgr, + ThreadMgrEventSink_OnUninitDocumentMgr, + ThreadMgrEventSink_OnSetFocus, + ThreadMgrEventSink_OnPushContext, + ThreadMgrEventSink_OnPopContext +}; - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); +static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut) +{ + ThreadMgrEventSink *This; - cnt = ITfDocumentMgr_Release(g_dm); - ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt); + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgrEventSink)); + if (This == NULL) + return E_OUTOFMEMORY; - hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); - ok(SUCCEEDED(hr),"GetFocus Failed\n"); - ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + This->ThreadMgrEventSinkVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl; + This->refCount = 1; - TextStoreACP_Constructor((IUnknown**)&ts); + *ppOut = (IUnknown *)This; + return S_OK; +} - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); +/******************************************************************************************** + * Stub text service for testing + ********************************************************************************************/ - hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie); - ok(SUCCEEDED(hr),"CreateContext Failed\n"); +static LONG TS_refCount; +static IClassFactory *cf; +static DWORD regid; - cnt = check_context_refcount(cxt); - test_OnPushContext = SINK_EXPECTED; - test_OnInitDocumentMgr = SINK_EXPECTED; - hr = ITfDocumentMgr_Push(g_dm, cxt); - ok(SUCCEEDED(hr),"Push Failed\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); - ok(test_OnInitDocumentMgr == SINK_FIRED, "OnInitDocumentMgr sink not fired\n"); +typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut); - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - cnt = ITfContext_Release(cxtTest); +typedef struct tagClassFactory +{ + const IClassFactoryVtbl *vtbl; + LONG ref; + LPFNCONSTRUCTOR ctor; +} ClassFactory; - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); +typedef struct tagTextService +{ + const ITfTextInputProcessorVtbl *TextInputProcessorVtbl; + LONG refCount; +} TextService; - check_context_refcount(cxt2); - test_OnPushContext = SINK_EXPECTED; - hr = ITfDocumentMgr_Push(g_dm, cxt2); - ok(SUCCEEDED(hr),"Push Failed\n"); - ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n"); +static void ClassFactory_Destructor(ClassFactory *This) +{ + HeapFree(GetProcessHeap(),0,This); + TS_refCount--; +} - cnt = check_context_refcount(cxt2); - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt2, "Wrong context on top\n"); - ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); +static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut) +{ + *ppvOut = NULL; + if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) + { + IClassFactory_AddRef(iface); + *ppvOut = iface; + return S_OK; + } - cnt = check_context_refcount(cxt); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); + return E_NOINTERFACE; +} - cnt = check_context_refcount(cxt3); - hr = ITfDocumentMgr_Push(g_dm, cxt3); - ok(!SUCCEEDED(hr),"Push Succeeded\n"); - ok(check_context_refcount(cxt3) == cnt, "Ref changed\n"); +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + ClassFactory *This = (ClassFactory *)iface; + return InterlockedIncrement(&This->ref); +} - cnt = check_context_refcount(cxt2); - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt2, "Wrong context on top\n"); - ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + ClassFactory *This = (ClassFactory *)iface; + ULONG ret = InterlockedDecrement(&This->ref); - cnt = check_context_refcount(cxt); - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on Base\n"); - ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); - ITfContext_Release(cxtTest); + if (ret == 0) + ClassFactory_Destructor(This); + return ret; +} - cnt = check_context_refcount(cxt2); - test_OnPopContext = SINK_EXPECTED; - hr = ITfDocumentMgr_Pop(g_dm, 0); - ok(SUCCEEDED(hr),"Pop Failed\n"); - ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n"); - ok(test_OnPopContext == SINK_FIRED, "OnPopContext sink not fired\n"); +static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut) +{ + ClassFactory *This = (ClassFactory *)iface; + HRESULT ret; + IUnknown *obj; - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ITfContext_Release(cxtTest); + ret = This->ctor(punkOuter, &obj); + if (FAILED(ret)) + return ret; + ret = IUnknown_QueryInterface(obj, iid, ppvOut); + IUnknown_Release(obj); + return ret; +} - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on base\n"); - ITfContext_Release(cxtTest); +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) +{ + if(fLock) + InterlockedIncrement(&TS_refCount); + else + InterlockedDecrement(&TS_refCount); - hr = ITfDocumentMgr_Pop(g_dm, 0); - ok(!SUCCEEDED(hr),"Pop Succeeded\n"); + return S_OK; +} - hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetTop Failed\n"); - ok(cxtTest == cxt, "Wrong context on top\n"); - ITfContext_Release(cxtTest); +static const IClassFactoryVtbl ClassFactoryVtbl = { + /* IUnknown */ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, - hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); - ok(SUCCEEDED(hr),"GetBase Failed\n"); - ok(cxtTest == cxt, "Wrong context on base\n"); - ITfContext_Release(cxtTest); + /* IClassFactory*/ + ClassFactory_CreateInstance, + ClassFactory_LockServer +}; - ITfContext_Release(cxt); - ITfContext_Release(cxt2); - ITfContext_Release(cxt3); +static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut) +{ + ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory)); + This->vtbl = &ClassFactoryVtbl; + This->ref = 1; + This->ctor = ctor; + *ppvOut = (LPVOID)This; + TS_refCount++; + return S_OK; } -static void test_endSession(void) +static void TextService_Destructor(TextService *This) { - HRESULT hr; - test_ShouldDeactivate = TRUE; - test_CurrentFocus = NULL; - test_PrevFocus = g_dm; - test_OnSetFocus = SINK_EXPECTED; - hr = ITfThreadMgr_Deactivate(g_tm); - ok(SUCCEEDED(hr),"Failed to Deactivate\n"); - ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); - test_OnSetFocus = SINK_UNEXPECTED; + HeapFree(GetProcessHeap(),0,This); } -static void test_TfGuidAtom(void) +static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut) { - GUID gtest,g1; - HRESULT hr; - TfGuidAtom atom1,atom2; - BOOL equal; + TextService *This = (TextService *)iface; + *ppvOut = NULL; - CoCreateGuid(>est); + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor)) + { + *ppvOut = This; + } - /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/ - /* - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n"); - */ - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); - hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2); - ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); - ok(atom1 == atom2,"atoms do not match\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); - ok(IsEqualGUID(&g1,>est),"guids do not match\n"); - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL); - ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n"); - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal); - ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); - ok(equal == TRUE,"Equal value invalid\n"); + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } - /* show that cid and tid TfClientIds are also TfGuidAtoms */ - hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal); - ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); - ok(equal == TRUE,"Equal value invalid\n"); - hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1); - ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); - ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); + return E_NOINTERFACE; } -static void test_ClientId(void) +static ULONG WINAPI TextService_AddRef(ITfTextInputProcessor *iface) { - ITfClientId *pcid; - TfClientId id1,id2; - HRESULT hr; - GUID g2; - - hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid); - ok(SUCCEEDED(hr),"Unable to aquire ITfClientId interface\n"); + TextService *This = (TextService *)iface; + return InterlockedIncrement(&This->refCount); +} - CoCreateGuid(&g2); +static ULONG WINAPI TextService_Release(ITfTextInputProcessor *iface) +{ + TextService *This = (TextService *)iface; + ULONG ret; - hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id1==id2,"Id's for GUID_NULL do not match\n"); - hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id2!=id1,"Id matches GUID_NULL\n"); - ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); - ok(id2!=cid,"Id for CLSID_FakeService matching cid\n"); - hr = ITfClientId_GetClientId(pcid,&g2,&id2); - ok(SUCCEEDED(hr),"GetClientId failed\n"); - ok(id2!=id1,"Id matches GUID_NULL\n"); - ok(id2!=tid,"Id for random guid matching tid\n"); - ok(id2!=cid,"Id for random guid matching cid\n"); - ITfClientId_Release(pcid); + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + TextService_Destructor(This); + return ret; } -START_TEST(inputprocessor) +static HRESULT WINAPI TextService_Activate(ITfTextInputProcessor *iface, + ITfThreadMgr *ptim, TfClientId id) { - if (SUCCEEDED(initialize())) - { - test_Register(); - test_RegisterCategory(); - test_EnumInputProcessorInfo(); - test_Enable(); - test_ThreadMgrAdviseSinks(); - test_Activate(); - test_startSession(); - test_TfGuidAtom(); - test_ClientId(); - test_KeystrokeMgr(); - test_endSession(); - test_EnumLanguageProfiles(); - test_FindClosestCategory(); - test_Disable(); - test_ThreadMgrUnadviseSinks(); - test_UnregisterCategory(); - test_Unregister(); - } - else - skip("Unable to create InputProcessor\n"); - cleanup(); + trace("TextService_Activate\n"); + ok(test_ShouldActivate,"Activation came unexpectedly\n"); + tid = id; + return S_OK; } -/********************************************************************** - * ITextStoreACP - **********************************************************************/ -typedef struct tagTextStoreACP +static HRESULT WINAPI TextService_Deactivate(ITfTextInputProcessor *iface) { - const ITextStoreACPVtbl *TextStoreACPVtbl; - LONG refCount; -} TextStoreACP; + trace("TextService_Deactivate\n"); + ok(test_ShouldDeactivate,"Deactivation came unexpectedly\n"); + return S_OK; +} -static void TextStoreACP_Destructor(TextStoreACP *This) +static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl= { - HeapFree(GetProcessHeap(),0,This); -} + TextService_QueryInterface, + TextService_AddRef, + TextService_Release, -static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut) + TextService_Activate, + TextService_Deactivate +}; + +static HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) { - TextStoreACP *This = (TextStoreACP *)iface; - *ppvOut = NULL; + TextService *This; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP)) - { - *ppvOut = This; - } + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextService)); + if (This == NULL) + return E_OUTOFMEMORY; - if (*ppvOut) - { - IUnknown_AddRef(iface); - return S_OK; - } + This->TextInputProcessorVtbl= &TextService_TextInputProcessorVtbl; + This->refCount = 1; - return E_NOINTERFACE; + *ppOut = (IUnknown *)This; + return S_OK; } -static ULONG WINAPI TextStoreACP_AddRef(ITextStoreACP *iface) +static HRESULT RegisterTextService(REFCLSID rclsid) { - TextStoreACP *This = (TextStoreACP *)iface; - return InterlockedIncrement(&This->refCount); + ClassFactory_Constructor( TextService_Constructor ,(LPVOID*)&cf); + return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id); } -static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface) +static HRESULT UnregisterTextService(void) { - TextStoreACP *This = (TextStoreACP *)iface; - ULONG ret; - - ret = InterlockedDecrement(&This->refCount); - if (ret == 0) - TextStoreACP_Destructor(This); - return ret; + return CoRevokeClassObject(regid); } -static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface, - REFIID riid, IUnknown *punk, DWORD dwMask) +/* + * The tests + */ + +DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3); +DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed); +DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); +DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31); +DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14); +DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43); +DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B); +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50); +DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72); +DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_DISABLED, 0x71a5b253,0x1951,0x466b,0x9f,0xbc,0x9c,0x88,0x08,0xfa,0x84,0xf2); +DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, 0x58273aad,0x01bb,0x4164,0x95,0xc6,0x75,0x5b,0xa0,0xb5,0x16,0x2d); +DEFINE_GUID(GUID_COMPARTMENT_HANDWRITING_OPENCLOSE, 0xf9ae2c6b,0x1866,0x4361,0xaf,0x72,0x7a,0xa3,0x09,0x48,0x89,0x0e); +DEFINE_GUID(GUID_COMPARTMENT_SPEECH_DISABLED, 0x56c5c607,0x0703,0x4e59,0x8e,0x52,0xcb,0xc8,0x4e,0x8b,0xbe,0x35); +DEFINE_GUID(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0x544d6a63,0xe2e8,0x4752,0xbb,0xd1,0x00,0x09,0x60,0xbc,0xa0,0x83); +DEFINE_GUID(GUID_COMPARTMENT_SPEECH_GLOBALSTATE, 0x2a54fe8e,0x0d08,0x460c,0xa7,0x5d,0x87,0x03,0x5f,0xf4,0x36,0xc5); +DEFINE_GUID(GUID_COMPARTMENT_PERSISTMENUENABLED, 0x575f3783,0x70c8,0x47c8,0xae,0x5d,0x91,0xa0,0x1a,0x1f,0x75,0x92); +DEFINE_GUID(GUID_COMPARTMENT_EMPTYCONTEXT, 0xd7487dbf,0x804e,0x41c5,0x89,0x4d,0xad,0x96,0xfd,0x4e,0xea,0x13); +DEFINE_GUID(GUID_COMPARTMENT_TIPUISTATUS, 0x148ca3ec,0x0366,0x401c,0x8d,0x75,0xed,0x97,0x8d,0x85,0xfb,0xc9); + +static HRESULT initialize(void) { - trace("\n"); - return S_OK; + HRESULT hr; + CoInitialize(NULL); + hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp); + if (SUCCEEDED(hr)) + hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm); + if (SUCCEEDED(hr)) + hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL, + CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm); + return hr; } -static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface, - IUnknown *punk) +static void cleanup(void) { - trace("\n"); - return S_OK; + if (g_ipp) + ITfInputProcessorProfiles_Release(g_ipp); + if (g_cm) + ITfCategoryMgr_Release(g_cm); + if (g_tm) + ITfThreadMgr_Release(g_tm); + CoUninitialize(); } -static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface, - DWORD dwLockFlags, HRESULT *phrSession) + +static void test_Register(void) { - trace("\n"); - return S_OK; + HRESULT hr; + + static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0}; + static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0}; + + hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid); + ok(SUCCEEDED(hr),"Unable to get current language id\n"); + trace("Current Language %x\n",gLangid); + + hr = RegisterTextService(&CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to register COM for TextService\n"); + hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr); + hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1); + ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr); } -static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface, - TS_STATUS *pdcs) + +static void test_Unregister(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService); + ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr); + UnregisterTextService(); } -static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface, - LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, - LONG *pacpResultEnd) + +static void test_EnumInputProcessorInfo(void) { - trace("\n"); - return S_OK; + IEnumGUID *ppEnum; + BOOL found = FALSE; + + if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum))) + { + ULONG fetched; + GUID g; + while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK) + { + if(IsEqualGUID(&g,&CLSID_FakeService)) + found = TRUE; + } + } + ok(found,"Did not find registered text service\n"); } -static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface, - ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) + +static void test_EnumLanguageProfiles(void) { - trace("\n"); - return S_OK; + BOOL found = FALSE; + IEnumTfLanguageProfiles *ppEnum; + if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum))) + { + TF_LANGUAGEPROFILE profile; + while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK) + { + if (IsEqualGUID(&profile.clsid,&CLSID_FakeService)) + { + found = TRUE; + ok(profile.langid == gLangid, "LangId Incorrect\n"); + ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n"); + ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n"); + } + } + } + ok(found,"Registered text service not found\n"); } -static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface, - ULONG ulCount, const TS_SELECTION_ACP *pSelection) + +static void test_RegisterCategory(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); + hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n"); } -static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface, - LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, - ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, - ULONG *pcRunInfoRet, LONG *pacpNext) + +static void test_UnregisterCategory(void) { - trace("\n"); - return S_OK; + HRESULT hr; + hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); + hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService); + ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n"); } -static HRESULT WINAPI TextStoreACP_SetText(ITextStoreACP *iface, - DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, - ULONG cch, TS_TEXTCHANGE *pChange) + +static void test_FindClosestCategory(void) { - trace("\n"); - return S_OK; + GUID output; + HRESULT hr; + const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING}; + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n"); + + hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3); + ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr); + ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n"); } -static HRESULT WINAPI TextStoreACP_GetFormattedText(ITextStoreACP *iface, - LONG acpStart, LONG acpEnd, IDataObject **ppDataObject) + +static void test_Enable(void) { - trace("\n"); - return S_OK; + HRESULT hr; + BOOL enabled = FALSE; + + hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE); + ok(SUCCEEDED(hr),"Failed to enable text service\n"); + hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled); + ok(SUCCEEDED(hr),"Failed to get enabled state\n"); + ok(enabled == TRUE,"enabled state incorrect\n"); } -static HRESULT WINAPI TextStoreACP_GetEmbedded(ITextStoreACP *iface, - LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) + +static void test_Disable(void) { - trace("\n"); - return S_OK; + HRESULT hr; + + trace("Disabling\n"); + hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE); + ok(SUCCEEDED(hr),"Failed to disable text service\n"); } -static HRESULT WINAPI TextStoreACP_QueryInsertEmbedded(ITextStoreACP *iface, - const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) + +static void test_ThreadMgrAdviseSinks(void) { - trace("\n"); - return S_OK; + ITfSource *source = NULL; + HRESULT hr; + IUnknown *sink; + + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); + ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); + if (!source) + return; + + hr = ThreadMgrEventSink_Constructor(&sink); + ok(hr == S_OK, "got %08x\n", hr); + if(FAILED(hr)) return; + + tmSinkRefCount = 1; + tmSinkCookie = 0; + hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie); + ok(SUCCEEDED(hr),"Failed to Advise Sink\n"); + ok(tmSinkCookie!=0,"Failed to get sink cookie\n"); + + /* Advising the sink adds a ref, Relesing here lets the object be deleted + when unadvised */ + tmSinkRefCount = 2; + IUnknown_Release(sink); + ITfSource_Release(source); } -static HRESULT WINAPI TextStoreACP_InsertEmbedded(ITextStoreACP *iface, - DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, - TS_TEXTCHANGE *pChange) + +static void test_ThreadMgrUnadviseSinks(void) { - trace("\n"); - return S_OK; + ITfSource *source = NULL; + HRESULT hr; + + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source); + ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n"); + if (!source) + return; + + tmSinkRefCount = 1; + hr = ITfSource_UnadviseSink(source, tmSinkCookie); + ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); + ITfSource_Release(source); } -static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface, - DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, - LONG *pacpEnd, TS_TEXTCHANGE *pChange) + +/********************************************************************** + * ITfKeyEventSink + **********************************************************************/ +typedef struct tagKeyEventSink { - trace("\n"); - return S_OK; -} -static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface, - DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, - TS_TEXTCHANGE *pChange) + const ITfKeyEventSinkVtbl *KeyEventSinkVtbl; + LONG refCount; +} KeyEventSink; + +static void KeyEventSink_Destructor(KeyEventSink *This) { - trace("\n"); - return S_OK; + HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI TextStoreACP_RequestSupportedAttrs(ITextStoreACP *iface, - DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) + +static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut) { - trace("\n"); - return S_OK; + KeyEventSink *This = (KeyEventSink *)iface; + *ppvOut = NULL; + + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink)) + { + *ppvOut = This; + } + + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; } -static HRESULT WINAPI TextStoreACP_RequestAttrsAtPosition(ITextStoreACP *iface, - LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags) + +static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface) { - trace("\n"); - return S_OK; + KeyEventSink *This = (KeyEventSink *)iface; + return InterlockedIncrement(&This->refCount); } -static HRESULT WINAPI TextStoreACP_RequestAttrsTransitioningAtPosition(ITextStoreACP *iface, - LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags) + +static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface) { - trace("\n"); - return S_OK; + KeyEventSink *This = (KeyEventSink *)iface; + ULONG ret; + + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + KeyEventSink_Destructor(This); + return ret; } -static HRESULT WINAPI TextStoreACP_FindNextAttrTransition(ITextStoreACP *iface, - LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, - DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset) + +static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface, + BOOL fForeground) { - trace("\n"); + sink_fire_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus"); return S_OK; } -static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface, - ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) + +static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface, - LONG *pacp) + +static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface, - TsViewCookie *pvcView) + +static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_GetACPFromPoint(ITextStoreACP *iface, - TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, - LONG *pacp) + +static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface, + ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_GetTextExt(ITextStoreACP *iface, - TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, - BOOL *pfClipped) + +static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface, + ITfContext *pic, REFGUID rguid, BOOL *pfEaten) { trace("\n"); return S_OK; } -static HRESULT WINAPI TextStoreACP_GetScreenExt(ITextStoreACP *iface, - TsViewCookie vcView, RECT *prc) + +static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl = { - trace("\n"); + KeyEventSink_QueryInterface, + KeyEventSink_AddRef, + KeyEventSink_Release, + + KeyEventSink_OnSetFocus, + KeyEventSink_OnTestKeyDown, + KeyEventSink_OnTestKeyUp, + KeyEventSink_OnKeyDown, + KeyEventSink_OnKeyUp, + KeyEventSink_OnPreservedKey +}; + +static HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut) +{ + KeyEventSink *This; + + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink)); + if (This == NULL) + return E_OUTOFMEMORY; + + This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl; + This->refCount = 1; + + *ppOut = (ITfKeyEventSink*)This; return S_OK; } -static HRESULT WINAPI TextStoreACP_GetWnd(ITextStoreACP *iface, - TsViewCookie vcView, HWND *phwnd) + + +static void test_KeystrokeMgr(void) { - trace("\n"); - return S_OK; + ITfKeystrokeMgr *keymgr= NULL; + HRESULT hr; + TF_PRESERVEDKEY tfpk; + BOOL preserved; + ITfKeyEventSink *sink = NULL; + + KeyEventSink_Constructor(&sink); + + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr); + ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n"); + + tfpk.uVKey = 'A'; + tfpk.uModifiers = TF_MOD_SHIFT; + + test_KEV_OnSetFocus = SINK_EXPECTED; + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); + sink_check_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); + ok(hr == CONNECT_E_ADVISELIMIT,"Wrong return, expected CONNECT_E_ADVISELIMIT\n"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,cid,sink,TRUE); + ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n"); + + hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + + hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); + + hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); + ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + + preserved = FALSE; + hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); + ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); + if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n"); + + hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); + + hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); + ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n"); + if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n"); + + hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); + ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n"); + + hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n"); + + ITfKeystrokeMgr_Release(keymgr); + ITfKeyEventSink_Release(sink); } -static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl = +static void test_Activate(void) { - TextStoreACP_QueryInterface, - TextStoreACP_AddRef, - TextStoreACP_Release, + HRESULT hr; - TextStoreACP_AdviseSink, - TextStoreACP_UnadviseSink, - TextStoreACP_RequestLock, - TextStoreACP_GetStatus, - TextStoreACP_QueryInsert, - TextStoreACP_GetSelection, - TextStoreACP_SetSelection, - TextStoreACP_GetText, - TextStoreACP_SetText, - TextStoreACP_GetFormattedText, - TextStoreACP_GetEmbedded, - TextStoreACP_QueryInsertEmbedded, - TextStoreACP_InsertEmbedded, - TextStoreACP_InsertTextAtSelection, - TextStoreACP_InsertEmbeddedAtSelection, - TextStoreACP_RequestSupportedAttrs, - TextStoreACP_RequestAttrsAtPosition, - TextStoreACP_RequestAttrsTransitioningAtPosition, - TextStoreACP_FindNextAttrTransition, - TextStoreACP_RetrieveRequestedAttrs, - TextStoreACP_GetEndACP, - TextStoreACP_GetActiveView, - TextStoreACP_GetACPFromPoint, - TextStoreACP_GetTextExt, - TextStoreACP_GetScreenExt, - TextStoreACP_GetWnd -}; + hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService); + ok(SUCCEEDED(hr),"Failed to Activate text service\n"); +} -HRESULT TextStoreACP_Constructor(IUnknown **ppOut) + +static void test_EnumContexts(ITfDocumentMgr *dm, ITfContext *search) { - TextStoreACP *This; + HRESULT hr; + IEnumTfContexts* pEnum; + BOOL found = FALSE; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACP)); - if (This == NULL) - return E_OUTOFMEMORY; + hr = ITfDocumentMgr_EnumContexts(dm,&pEnum); + ok(SUCCEEDED(hr),"EnumContexts failed\n"); + if (SUCCEEDED(hr)) + { + ULONG fetched; + ITfContext *cxt; + while (IEnumTfContexts_Next(pEnum, 1, &cxt, &fetched) == S_OK) + { + if (!search) + found = TRUE; + else if (search == cxt) + found = TRUE; + ITfContext_Release(cxt); + } + IEnumTfContexts_Release(pEnum); + } + if (search) + ok(found,"Did not find proper ITfContext\n"); + else + ok(!found,"Found an ITfContext we should should not have\n"); +} + +static void test_EnumDocumentMgr(ITfThreadMgr *tm, ITfDocumentMgr *search, ITfDocumentMgr *absent) +{ + HRESULT hr; + IEnumTfDocumentMgrs* pEnum; + BOOL found = FALSE; + BOOL notfound = TRUE; - This->TextStoreACPVtbl = &TextStoreACP_TextStoreACPVtbl; - This->refCount = 1; + hr = ITfThreadMgr_EnumDocumentMgrs(tm,&pEnum); + ok(SUCCEEDED(hr),"EnumDocumentMgrs failed\n"); + if (SUCCEEDED(hr)) + { + ULONG fetched; + ITfDocumentMgr *dm; + while (IEnumTfDocumentMgrs_Next(pEnum, 1, &dm, &fetched) == S_OK) + { + if (!search) + found = TRUE; + else if (search == dm) + found = TRUE; + if (absent && dm == absent) + notfound = FALSE; + ITfDocumentMgr_Release(dm); + } + IEnumTfDocumentMgrs_Release(pEnum); + } + if (search) + ok(found,"Did not find proper ITfDocumentMgr\n"); + else + ok(!found,"Found an ITfDocumentMgr we should should not have\n"); + if (absent) + ok(notfound,"Found an ITfDocumentMgr we believe should be absent\n"); +} - *ppOut = (IUnknown *)This; - return S_OK; +static inline int check_context_refcount(ITfContext *iface) +{ + IUnknown_AddRef(iface); + return IUnknown_Release(iface); } + /********************************************************************** - * ITfThreadMgrEventSink + * ITfTextEditSink **********************************************************************/ -typedef struct tagThreadMgrEventSink +typedef struct tagTextEditSink { - const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; + const ITfTextEditSinkVtbl *TextEditSinkVtbl; LONG refCount; -} ThreadMgrEventSink; +} TextEditSink; -static void ThreadMgrEventSink_Destructor(ThreadMgrEventSink *This) +static void TextEditSink_Destructor(TextEditSink *This) { HeapFree(GetProcessHeap(),0,This); } -static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) +static HRESULT WINAPI TextEditSink_QueryInterface(ITfTextEditSink *iface, REFIID iid, LPVOID *ppvOut) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + TextEditSink *This = (TextEditSink *)iface; *ppvOut = NULL; - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgrEventSink)) + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextEditSink)) { *ppvOut = This; } @@ -1022,290 +1281,822 @@ static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *i return E_NOINTERFACE; } -static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface) +static ULONG WINAPI TextEditSink_AddRef(ITfTextEditSink *iface) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; - ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); + TextEditSink *This = (TextEditSink *)iface; return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface) +static ULONG WINAPI TextEditSink_Release(ITfTextEditSink *iface) { - ThreadMgrEventSink *This = (ThreadMgrEventSink *)iface; + TextEditSink *This = (TextEditSink *)iface; ULONG ret; - ok (tmSinkRefCount == This->refCount,"ThreadMgrEventSink refcount off %i vs %i\n",This->refCount,tmSinkRefCount); ret = InterlockedDecrement(&This->refCount); if (ret == 0) - ThreadMgrEventSink_Destructor(This); + TextEditSink_Destructor(This); return ret; } -static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdim) +static HRESULT WINAPI TextEditSink_OnEndEdit(ITfTextEditSink *iface, + ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord) { - ok(test_OnInitDocumentMgr == SINK_EXPECTED, "Unexpected OnInitDocumentMgr sink\n"); - test_OnInitDocumentMgr = SINK_FIRED; + sink_fire_ok(&test_OnEndEdit,"TextEditSink_OnEndEdit"); return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdim) +static const ITfTextEditSinkVtbl TextEditSink_TextEditSinkVtbl = { - trace("\n"); - return S_OK; -} + TextEditSink_QueryInterface, + TextEditSink_AddRef, + TextEditSink_Release, -static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface, -ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) + TextEditSink_OnEndEdit +}; + +static HRESULT TextEditSink_Constructor(ITfTextEditSink **ppOut) { - ok(test_OnSetFocus == SINK_EXPECTED, "Unexpected OnSetFocus sink\n"); - ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n"); - ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n"); - test_OnSetFocus = SINK_FIRED; + TextEditSink *This; + + *ppOut = NULL; + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextEditSink)); + if (This == NULL) + return E_OUTOFMEMORY; + + This->TextEditSinkVtbl = &TextEditSink_TextEditSinkVtbl; + This->refCount = 1; + + *ppOut = (ITfTextEditSink*)This; return S_OK; } -static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface, -ITfContext *pic) +static void test_startSession(void) { - ok(test_OnPushContext == SINK_EXPECTED, "Unexpected OnPushContext sink\n"); - test_OnPushContext = SINK_FIRED; - return S_OK; + HRESULT hr; + DWORD cnt; + DWORD editCookie; + ITfDocumentMgr *dmtest; + ITfContext *cxt,*cxt2,*cxt3,*cxtTest; + ITextStoreACP *ts; + TfClientId cid2 = 0; + + hr = ITfThreadMgr_Deactivate(g_tm); + ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n"); + + test_ShouldActivate = TRUE; + hr = ITfThreadMgr_Activate(g_tm,&cid); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok(cid != tid,"TextService id mistakenly matches Client id\n"); + + test_ShouldActivate = FALSE; + hr = ITfThreadMgr_Activate(g_tm,&cid2); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok (cid == cid2, "Second activate client ID does not match\n"); + + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); + + test_EnumDocumentMgr(g_tm,NULL,NULL); + + hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm); + ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); + + test_EnumDocumentMgr(g_tm,g_dm,NULL); + + hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dmtest); + ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); + + test_EnumDocumentMgr(g_tm,dmtest,NULL); + + ITfDocumentMgr_Release(dmtest); + test_EnumDocumentMgr(g_tm,g_dm,dmtest); + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(dmtest == NULL,"Initial focus not null\n"); + + test_CurrentFocus = g_dm; + test_PrevFocus = NULL; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_SetFocus(g_tm,g_dm); + ok(SUCCEEDED(hr),"SetFocus Failed\n"); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + + cnt = ITfDocumentMgr_Release(g_dm); + ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt); + + hr = ITfThreadMgr_GetFocus(g_tm,&dmtest); + ok(SUCCEEDED(hr),"GetFocus Failed\n"); + ok(g_dm == dmtest,"Expected DocumentMgr not focused\n"); + ITfDocumentMgr_Release(dmtest); + + TextStoreACP_Constructor((IUnknown**)&ts); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie); + ok(SUCCEEDED(hr),"CreateContext Failed\n"); + + test_EnumContexts(g_dm, NULL); + + hr = ITfContext_GetDocumentMgr(cxt,&dmtest); + ok(hr == S_OK, "ITfContext_GetDocumentMgr failed with %x\n",hr); + ok(dmtest == g_dm, "Wrong documentmgr\n"); + ITfDocumentMgr_Release(dmtest); + + cnt = check_context_refcount(cxt); + test_OnPushContext = SINK_EXPECTED; + test_ACP_AdviseSink = SINK_EXPECTED; + test_OnInitDocumentMgr = SINK_EXPECTED; + hr = ITfDocumentMgr_Push(g_dm, cxt); + ok(SUCCEEDED(hr),"Push Failed\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + sink_check_ok(&test_OnPushContext,"OnPushContext"); + sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr"); + sink_check_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink"); + + test_EnumContexts(g_dm, cxt); + + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + cnt = ITfContext_Release(cxtTest); + + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + check_context_refcount(cxt2); + test_OnPushContext = SINK_EXPECTED; + hr = ITfDocumentMgr_Push(g_dm, cxt2); + ok(SUCCEEDED(hr),"Push Failed\n"); + sink_check_ok(&test_OnPushContext,"OnPushContext"); + + cnt = check_context_refcount(cxt2); + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt2, "Wrong context on top\n"); + ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + cnt = check_context_refcount(cxt); + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + cnt = check_context_refcount(cxt3); + hr = ITfDocumentMgr_Push(g_dm, cxt3); + ok(FAILED(hr),"Push Succeeded\n"); + ok(check_context_refcount(cxt3) == cnt, "Ref changed\n"); + + cnt = check_context_refcount(cxt2); + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt2, "Wrong context on top\n"); + ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + cnt = check_context_refcount(cxt); + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on Base\n"); + ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n"); + ITfContext_Release(cxtTest); + + cnt = check_context_refcount(cxt2); + test_OnPopContext = SINK_EXPECTED; + hr = ITfDocumentMgr_Pop(g_dm, 0); + ok(SUCCEEDED(hr),"Pop Failed\n"); + ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n"); + sink_check_ok(&test_OnPopContext,"OnPopContext"); + + dmtest = (void *)0xfeedface; + hr = ITfContext_GetDocumentMgr(cxt2,&dmtest); + ok(hr == S_FALSE, "ITfContext_GetDocumentMgr wrong rc %x\n",hr); + ok(dmtest == NULL,"returned documentmgr should be null\n"); + + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ITfContext_Release(cxtTest); + + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on base\n"); + ITfContext_Release(cxtTest); + + hr = ITfDocumentMgr_Pop(g_dm, 0); + ok(FAILED(hr),"Pop Succeeded\n"); + + hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetTop Failed\n"); + ok(cxtTest == cxt, "Wrong context on top\n"); + ITfContext_Release(cxtTest); + + hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest); + ok(SUCCEEDED(hr),"GetBase Failed\n"); + ok(cxtTest == cxt, "Wrong context on base\n"); + ITfContext_Release(cxtTest); + + ITfContext_Release(cxt); + ITfContext_Release(cxt2); + ITfContext_Release(cxt3); } -static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface, -ITfContext *pic) +static void test_endSession(void) { - ok(test_OnPopContext == SINK_EXPECTED, "Unexpected OnPopContext sink\n"); - test_OnPopContext = SINK_FIRED; - return S_OK; + HRESULT hr; + test_ShouldDeactivate = TRUE; + test_CurrentFocus = NULL; + test_PrevFocus = g_dm; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + test_OnSetFocus = SINK_UNEXPECTED; } -static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl = +static void test_TfGuidAtom(void) { - ThreadMgrEventSink_QueryInterface, - ThreadMgrEventSink_AddRef, - ThreadMgrEventSink_Release, + GUID gtest,g1; + HRESULT hr; + TfGuidAtom atom1,atom2; + BOOL equal; + + CoCreateGuid(>est); + + /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/ + /* + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n"); + */ + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); + hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2); + ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n"); + ok(atom1 == atom2,"atoms do not match\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); + ok(IsEqualGUID(&g1,>est),"guids do not match\n"); + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL); + ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n"); + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal); + ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); + ok(equal == TRUE,"Equal value invalid\n"); - ThreadMgrEventSink_OnInitDocumentMgr, - ThreadMgrEventSink_OnUninitDocumentMgr, - ThreadMgrEventSink_OnSetFocus, - ThreadMgrEventSink_OnPushContext, - ThreadMgrEventSink_OnPopContext -}; + /* show that cid and tid TfClientIds are also TfGuidAtoms */ + hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal); + ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); + ok(equal == TRUE,"Equal value invalid\n"); + hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1); + ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); + ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); +} -HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut) +static void test_ClientId(void) { - ThreadMgrEventSink *This; + ITfClientId *pcid; + TfClientId id1,id2; + HRESULT hr; + GUID g2; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgrEventSink)); - if (This == NULL) - return E_OUTOFMEMORY; + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid); + ok(SUCCEEDED(hr),"Unable to acquire ITfClientId interface\n"); - This->ThreadMgrEventSinkVtbl = &ThreadMgrEventSink_ThreadMgrEventSinkVtbl; - This->refCount = 1; + CoCreateGuid(&g2); - *ppOut = (IUnknown *)This; - return S_OK; + hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id1==id2,"Id's for GUID_NULL do not match\n"); + hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id2!=id1,"Id matches GUID_NULL\n"); + ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); + ok(id2!=cid,"Id for CLSID_FakeService matching cid\n"); + hr = ITfClientId_GetClientId(pcid,&g2,&id2); + ok(SUCCEEDED(hr),"GetClientId failed\n"); + ok(id2!=id1,"Id matches GUID_NULL\n"); + ok(id2!=tid,"Id for random guid matching tid\n"); + ok(id2!=cid,"Id for random guid matching cid\n"); + ITfClientId_Release(pcid); } - -/******************************************************************************************** - * Stub text service for testing - ********************************************************************************************/ - -static LONG TS_refCount; -static IClassFactory *cf; -static DWORD regid; - -typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut); - -typedef struct tagClassFactory -{ - const IClassFactoryVtbl *vtbl; - LONG ref; - LPFNCONSTRUCTOR ctor; -} ClassFactory; - -typedef struct tagTextService +/********************************************************************** + * ITfEditSession + **********************************************************************/ +typedef struct tagEditSession { - const ITfTextInputProcessorVtbl *TextInputProcessorVtbl; + const ITfEditSessionVtbl *EditSessionVtbl; LONG refCount; -} TextService; +} EditSession; -static void ClassFactory_Destructor(ClassFactory *This) +static void EditSession_Destructor(EditSession *This) { HeapFree(GetProcessHeap(),0,This); - TS_refCount--; } -static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut) +static HRESULT WINAPI EditSession_QueryInterface(ITfEditSession *iface, REFIID iid, LPVOID *ppvOut) { + EditSession *This = (EditSession *)iface; *ppvOut = NULL; - if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) + + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfEditSession)) { - IClassFactory_AddRef(iface); - *ppvOut = iface; + *ppvOut = This; + } + + if (*ppvOut) + { + IUnknown_AddRef(iface); return S_OK; } return E_NOINTERFACE; } -static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +static ULONG WINAPI EditSession_AddRef(ITfEditSession *iface) { - ClassFactory *This = (ClassFactory *)iface; - return InterlockedIncrement(&This->ref); + EditSession *This = (EditSession *)iface; + return InterlockedIncrement(&This->refCount); } -static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +static ULONG WINAPI EditSession_Release(ITfEditSession *iface) { - ClassFactory *This = (ClassFactory *)iface; - ULONG ret = InterlockedDecrement(&This->ref); + EditSession *This = (EditSession *)iface; + ULONG ret; + ret = InterlockedDecrement(&This->refCount); if (ret == 0) - ClassFactory_Destructor(This); + EditSession_Destructor(This); return ret; } -static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut) +static void test_InsertAtSelection(TfEditCookie ec, ITfContext *cxt) { - ClassFactory *This = (ClassFactory *)iface; - HRESULT ret; - IUnknown *obj; + HRESULT hr; + ITfInsertAtSelection *iis; + ITfRange *range=NULL; + static const WCHAR txt[] = {'H','e','l','l','o',' ','W','o','r','l','d',0}; + + hr = ITfContext_QueryInterface(cxt, &IID_ITfInsertAtSelection , (LPVOID*)&iis); + ok(SUCCEEDED(hr),"Failed to get ITfInsertAtSelection interface\n"); + test_ACP_InsertTextAtSelection = SINK_EXPECTED; + hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, txt, 11, &range); + ok(SUCCEEDED(hr),"ITfInsertAtSelection_InsertTextAtSelection failed %x\n",hr); + sink_check_ok(&test_ACP_InsertTextAtSelection,"InsertTextAtSelection"); + ok(range != NULL,"No range returned\n"); + ITfRange_Release(range); + ITfInsertAtSelection_Release(iis); +} + +static HRESULT WINAPI EditSession_DoEditSession(ITfEditSession *iface, +TfEditCookie ec) +{ + ITfContext *cxt; + ITfDocumentMgr *dm; + ITfRange *range; + TF_SELECTION selection; + ULONG fetched; + HRESULT hr; - ret = This->ctor(punkOuter, &obj); - if (FAILED(ret)) - return ret; - ret = IUnknown_QueryInterface(obj, iid, ppvOut); - IUnknown_Release(obj); - return ret; -} + sink_fire_ok(&test_DoEditSession,"EditSession_DoEditSession"); + sink_check_ok(&test_ACP_RequestLock,"RequestLock"); -static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) -{ - if(fLock) - InterlockedIncrement(&TS_refCount); - else - InterlockedDecrement(&TS_refCount); + ITfThreadMgr_GetFocus(g_tm, &dm); + ITfDocumentMgr_GetTop(dm,&cxt); - return S_OK; + hr = ITfContext_GetStart(cxt,ec,NULL); + ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr); + + range = (ITfRange*)0xdeaddead; + hr = ITfContext_GetStart(cxt,0xdeadcafe,&range); + ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr); + ok(range == NULL,"Range not set to NULL\n"); + + hr = ITfContext_GetStart(cxt,ec,&range); + ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr); + ok(range != NULL,"Range set to NULL\n"); + + ITfRange_Release(range); + + hr = ITfContext_GetEnd(cxt,ec,NULL); + ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr); + + range = (ITfRange*)0xdeaddead; + hr = ITfContext_GetEnd(cxt,0xdeadcafe,&range); + ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr); + ok(range == NULL,"Range not set to NULL\n"); + + test_ACP_GetEndACP = SINK_EXPECTED; + hr = ITfContext_GetEnd(cxt,ec,&range); + ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr); + ok(range != NULL,"Range set to NULL\n"); + sink_check_ok(&test_ACP_GetEndACP,"GetEndACP"); + + ITfRange_Release(range); + + selection.range = NULL; + test_ACP_GetSelection = SINK_EXPECTED; + hr = ITfContext_GetSelection(cxt, ec, TF_DEFAULT_SELECTION, 1, &selection, &fetched); + ok(SUCCEEDED(hr),"ITfContext_GetSelection failed\n"); + ok(fetched == 1,"fetched incorrect\n"); + ok(selection.range != NULL,"NULL range\n"); + sink_check_ok(&test_ACP_GetSelection,"ACP_GetSepection"); + ITfRange_Release(selection.range); + + test_InsertAtSelection(ec, cxt); + + test_ACP_GetEndACP = SINK_EXPECTED; + hr = ITfContext_GetEnd(cxt,ec,&range); + ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr); + ok(range != NULL,"Range set to NULL\n"); + sink_check_ok(&test_ACP_GetEndACP,"GetEndACP"); + + selection.range = range; + selection.style.ase = TF_AE_NONE; + selection.style.fInterimChar = FALSE; + test_ACP_SetSelection = SINK_EXPECTED; + hr = ITfContext_SetSelection(cxt, ec, 1, &selection); + sink_check_ok(&test_ACP_SetSelection,"SetSelection"); + ITfRange_Release(range); + + ITfContext_Release(cxt); + ITfDocumentMgr_Release(dm); + return 0xdeadcafe; } -static const IClassFactoryVtbl ClassFactoryVtbl = { - /* IUnknown */ - ClassFactory_QueryInterface, - ClassFactory_AddRef, - ClassFactory_Release, +static const ITfEditSessionVtbl EditSession_EditSessionVtbl = +{ + EditSession_QueryInterface, + EditSession_AddRef, + EditSession_Release, - /* IClassFactory*/ - ClassFactory_CreateInstance, - ClassFactory_LockServer + EditSession_DoEditSession }; -static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut) +static HRESULT EditSession_Constructor(ITfEditSession **ppOut) { - ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory)); - This->vtbl = &ClassFactoryVtbl; - This->ref = 1; - This->ctor = ctor; - *ppvOut = (LPVOID)This; - TS_refCount++; + EditSession *This; + + *ppOut = NULL; + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EditSession)); + if (This == NULL) + return E_OUTOFMEMORY; + + This->EditSessionVtbl = &EditSession_EditSessionVtbl; + This->refCount = 1; + + *ppOut = (ITfEditSession*)This; return S_OK; } -static void TextService_Destructor(TextService *This) +static void test_TStoApplicationText(void) { - HeapFree(GetProcessHeap(),0,This); -} + HRESULT hr, hrSession; + ITfEditSession *es; + ITfContext *cxt; + ITfDocumentMgr *dm; + ITfTextEditSink *sink; + ITfSource *source = NULL; + DWORD editSinkCookie = -1; -static HRESULT WINAPI TextService_QueryInterface(ITfTextInputProcessor *iface, REFIID iid, LPVOID *ppvOut) -{ - TextService *This = (TextService *)iface; - *ppvOut = NULL; + ITfThreadMgr_GetFocus(g_tm, &dm); + EditSession_Constructor(&es); + ITfDocumentMgr_GetTop(dm,&cxt); - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextInputProcessor)) + TextEditSink_Constructor(&sink); + hr = ITfContext_QueryInterface(cxt,&IID_ITfSource,(LPVOID*)&source); + ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for Context\n"); + if (source) { - *ppvOut = This; + hr = ITfSource_AdviseSink(source, &IID_ITfTextEditSink, (LPVOID)sink, &editSinkCookie); + ok(SUCCEEDED(hr),"Failed to advise Sink\n"); + ok(editSinkCookie != -1,"Failed to get sink cookie\n"); } - if (*ppvOut) + hrSession = 0xfeedface; + /* Test no premissions flags */ + hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC, &hrSession); + ok(hr == E_INVALIDARG,"RequestEditSession should have failed with %x not %x\n",E_INVALIDARG,hr); + ok(hrSession == E_FAIL,"hrSession should be %x not %x\n",E_FAIL,hrSession); + + documentStatus = TS_SD_READONLY; + hrSession = 0xfeedface; + test_ACP_GetStatus = SINK_EXPECTED; + hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession); + ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n"); + ok(hrSession == TS_E_READONLY,"Unexpected hrSession (%x)\n",hrSession); + sink_check_ok(&test_ACP_GetStatus,"GetStatus"); + + /* signal a change to allow readwrite sessions */ + documentStatus = 0; + test_ACP_RequestLock = SINK_EXPECTED; + ITextStoreACPSink_OnStatusChange(ACPSink,documentStatus); + sink_check_ok(&test_ACP_RequestLock,"RequestLock"); + + test_ACP_GetStatus = SINK_EXPECTED; + test_ACP_RequestLock = SINK_EXPECTED; + test_DoEditSession = SINK_EXPECTED; + hrSession = 0xfeedface; + test_OnEndEdit = SINK_EXPECTED; + hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession); + ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n"); + sink_check_ok(&test_OnEndEdit,"OnEndEdit"); + sink_check_ok(&test_DoEditSession,"DoEditSession"); + sink_check_ok(&test_ACP_GetStatus,"GetStatus"); + ok(hrSession == 0xdeadcafe,"Unexpected hrSession (%x)\n",hrSession); + + if (source) { - IUnknown_AddRef(iface); - return S_OK; + hr = ITfSource_UnadviseSink(source, editSinkCookie); + ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); + ITfTextEditSink_Release(sink); + ITfSource_Release(source); } - return E_NOINTERFACE; + ITfContext_Release(cxt); + ITfDocumentMgr_Release(dm); + ITfEditSession_Release(es); } -static ULONG WINAPI TextService_AddRef(ITfTextInputProcessor *iface) +static void enum_compartments(ITfCompartmentMgr *cmpmgr, REFGUID present, REFGUID absent) { - TextService *This = (TextService *)iface; - return InterlockedIncrement(&This->refCount); + BOOL found,found2; + IEnumGUID *ppEnum; + found = FALSE; + found2 = FALSE; + if (SUCCEEDED(ITfCompartmentMgr_EnumCompartments(cmpmgr, &ppEnum))) + { + ULONG fetched; + GUID g; + while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK) + { + WCHAR str[50]; + CHAR strA[50]; + StringFromGUID2(&g,str,sizeof(str)/sizeof(str[0])); + WideCharToMultiByte(CP_ACP,0,str,-1,strA,sizeof(strA),0,0); + trace("found %s\n",strA); + if (present && IsEqualGUID(present,&g)) + found = TRUE; + if (absent && IsEqualGUID(absent, &g)) + found2 = TRUE; + } + IEnumGUID_Release(ppEnum); + } + if (present) + ok(found,"Did not find compartment\n"); + if (absent) + ok(!found2,"Found compartment that should be absent\n"); } -static ULONG WINAPI TextService_Release(ITfTextInputProcessor *iface) +static void test_Compartments(void) { - TextService *This = (TextService *)iface; - ULONG ret; + ITfContext *cxt; + ITfDocumentMgr *dm; + ITfCompartmentMgr *cmpmgr; + ITfCompartment *cmp; + HRESULT hr; - ret = InterlockedDecrement(&This->refCount); - if (ret == 0) - TextService_Destructor(This); - return ret; -} + ITfThreadMgr_GetFocus(g_tm, &dm); + ITfDocumentMgr_GetTop(dm,&cxt); + + /* Global */ + hr = ITfThreadMgr_GetGlobalCompartment(g_tm, &cmpmgr); + ok(SUCCEEDED(hr),"GetGlobalCompartment failed\n"); + hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_SPEECH_OPENCLOSE, &cmp); + ok(SUCCEEDED(hr),"GetCompartment failed\n"); + ITfCompartment_Release(cmp); + enum_compartments(cmpmgr,&GUID_COMPARTMENT_SPEECH_OPENCLOSE,NULL); + ITfCompartmentMgr_Release(cmpmgr); + + /* Thread */ + hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr); + ok(SUCCEEDED(hr),"ThreadMgr QI for IID_ITfCompartmentMgr failed\n"); + hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &CLSID_FakeService, &cmp); + ok(SUCCEEDED(hr),"GetCompartment failed\n"); + enum_compartments(cmpmgr,&CLSID_FakeService,&GUID_COMPARTMENT_SPEECH_OPENCLOSE); + ITfCompartmentMgr_ClearCompartment(cmpmgr,tid,&CLSID_FakeService); + enum_compartments(cmpmgr,NULL,&CLSID_FakeService); + ITfCompartmentMgr_Release(cmpmgr); + ITfCompartment_Release(cmp); + + /* DocumentMgr */ + hr = ITfDocumentMgr_QueryInterface(dm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr); + ok(SUCCEEDED(hr),"DocumentMgr QI for IID_ITfCompartmentMgr failed\n"); + + hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_PERSISTMENUENABLED, &cmp); + ok(SUCCEEDED(hr),"GetCompartment failed\n"); + enum_compartments(cmpmgr,&GUID_COMPARTMENT_PERSISTMENUENABLED,&GUID_COMPARTMENT_SPEECH_OPENCLOSE); + ITfCompartmentMgr_Release(cmpmgr); + + /* Context */ + hr = ITfContext_QueryInterface(cxt, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr); + ok(SUCCEEDED(hr),"Context QI for IID_ITfCompartmentMgr failed\n"); + enum_compartments(cmpmgr,NULL,&GUID_COMPARTMENT_PERSISTMENUENABLED); + ITfCompartmentMgr_Release(cmpmgr); -static HRESULT WINAPI TextService_Activate(ITfTextInputProcessor *iface, - ITfThreadMgr *ptim, TfClientId id) -{ - trace("TextService_Activate\n"); - ok(test_ShouldActivate,"Activation came unexpectedly\n"); - tid = id; - return S_OK; + ITfContext_Release(cxt); + ITfDocumentMgr_Release(dm); } -static HRESULT WINAPI TextService_Deactivate(ITfTextInputProcessor *iface) +static void processPendingMessages(void) { - trace("TextService_Deactivate\n"); - ok(test_ShouldDeactivate,"Deactivation came unexpectedly\n"); - return S_OK; + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } -static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl= +static void test_AssociateFocus(void) { - TextService_QueryInterface, - TextService_AddRef, - TextService_Release, + ITfDocumentMgr *dm1, *dm2, *olddm, *dmcheck, *dmorig; + HWND wnd1, wnd2, wnd3; + HRESULT hr; - TextService_Activate, - TextService_Deactivate -}; + ITfThreadMgr_GetFocus(g_tm, &dmorig); + test_CurrentFocus = NULL; + test_PrevFocus = dmorig; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_SetFocus(g_tm,NULL); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + ITfDocumentMgr_Release(dmorig); -HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) -{ - TextService *This; - if (pUnkOuter) - return CLASS_E_NOAGGREGATION; + hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm1); + ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextService)); - if (This == NULL) - return E_OUTOFMEMORY; + hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm2); + ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); - This->TextInputProcessorVtbl= &TextService_TextInputProcessorVtbl; - This->refCount = 1; + wnd1 = CreateWindow("edit",NULL,WS_POPUP,0,0,200,60,NULL,NULL,NULL,NULL); + ok(wnd1!=NULL,"Unable to create window 1\n"); + wnd2 = CreateWindow("edit",NULL,WS_POPUP,0,65,200,60,NULL,NULL,NULL,NULL); + ok(wnd2!=NULL,"Unable to create window 2\n"); + wnd3 = CreateWindow("edit",NULL,WS_POPUP,0,130,200,60,NULL,NULL,NULL,NULL); + ok(wnd3!=NULL,"Unable to create window 3\n"); - *ppOut = (IUnknown *)This; - return S_OK; -} + processPendingMessages(); -HRESULT RegisterTextService(REFCLSID rclsid) -{ - ClassFactory_Constructor( TextService_Constructor ,(LPVOID*)&cf); - return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id); + test_OnInitDocumentMgr = SINK_OPTIONAL; /* Vista and greater */ + test_OnPushContext = SINK_OPTIONAL; /* Vista and greater */ + + ShowWindow(wnd1,SW_SHOWNORMAL); + SetFocus(wnd1); + sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr"); + sink_check_ok(&test_OnPushContext,"OnPushContext"); + + test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */ + ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus); + test_CurrentFocus = FOCUS_IGNORE; /* This is a default system context */ + processPendingMessages(); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + test_CurrentFocus = dm1; + test_PrevFocus = FOCUS_IGNORE; + test_OnSetFocus = SINK_EXPECTED; + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,dm1,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + processPendingMessages(); + + ITfThreadMgr_GetFocus(g_tm, &dmcheck); + ok(dmcheck == dm1, "Expected DocumentMgr not focused\n"); + ITfDocumentMgr_Release(dmcheck); + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + processPendingMessages(); + ITfThreadMgr_GetFocus(g_tm, &dmcheck); + ok(dmcheck == dm1, "Expected DocumentMgr not focused\n"); + ITfDocumentMgr_Release(dmcheck); + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,dm2,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + processPendingMessages(); + ITfThreadMgr_GetFocus(g_tm, &dmcheck); + ok(dmcheck == dm1, "Expected DocumentMgr not focused\n"); + ITfDocumentMgr_Release(dmcheck); + + test_CurrentFocus = dm2; + test_PrevFocus = dm1; + test_OnSetFocus = SINK_OPTIONAL; /* wine and Winxp */ + ShowWindow(wnd2,SW_SHOWNORMAL); + SetFocus(wnd2); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + test_CurrentFocus = FOCUS_IGNORE; /* occasional wine race */ + test_PrevFocus = FOCUS_IGNORE; /* occasional wine race */ + test_OnSetFocus = SINK_IGNORE; /* occasional wine race */ + processPendingMessages(); + + ShowWindow(wnd3,SW_SHOWNORMAL); + SetFocus(wnd3); + processPendingMessages(); + + test_CurrentFocus = dm1; + test_PrevFocus = dm2; + test_OnSetFocus = SINK_EXPECTED; + SetFocus(wnd1); + processPendingMessages(); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,NULL,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + ok(olddm == dm2, "incorrect old DocumentMgr returned\n"); + ITfDocumentMgr_Release(olddm); + + test_CurrentFocus = dmorig; + test_PrevFocus = dm1; + test_OnSetFocus = SINK_EXPECTED; + test_ACP_GetStatus = SINK_EXPECTED; + ITfThreadMgr_SetFocus(g_tm,dmorig); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + test_CurrentFocus = FOCUS_IGNORE; /* NULL on XP, system default on Vista */ + test_PrevFocus = dmorig; + test_OnSetFocus = SINK_EXPECTED; + SetFocus(wnd3); + processPendingMessages(); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,NULL,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + ok(olddm == dm2, "incorrect old DocumentMgr returned\n"); + ITfDocumentMgr_Release(olddm); + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,NULL,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + ok(olddm == dm1, "incorrect old DocumentMgr returned\n"); + ITfDocumentMgr_Release(olddm); + + SetFocus(wnd2); + processPendingMessages(); + SetFocus(wnd1); + processPendingMessages(); + + ITfDocumentMgr_Release(dm1); + ITfDocumentMgr_Release(dm2); + + test_CurrentFocus = dmorig; + test_PrevFocus = FOCUS_IGNORE; + test_OnSetFocus = SINK_EXPECTED; + test_ACP_GetStatus = SINK_IGNORE; + ITfThreadMgr_SetFocus(g_tm,dmorig); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + + DestroyWindow(wnd1); + DestroyWindow(wnd2); + test_OnPopContext = SINK_OPTIONAL; /* Vista and greater */ + test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */ + ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus); + test_CurrentFocus = NULL; + DestroyWindow(wnd3); + sink_check_ok(&test_OnSetFocus,"OnSetFocus"); + sink_check_ok(&test_OnPopContext,"OnPopContext"); } -HRESULT UnregisterTextService() +START_TEST(inputprocessor) { - return CoRevokeClassObject(regid); + if (SUCCEEDED(initialize())) + { + test_Register(); + test_RegisterCategory(); + test_EnumLanguageProfiles(); + test_EnumInputProcessorInfo(); + test_Enable(); + test_ThreadMgrAdviseSinks(); + test_Activate(); + test_startSession(); + test_TfGuidAtom(); + test_ClientId(); + test_KeystrokeMgr(); + test_TStoApplicationText(); + test_Compartments(); + test_AssociateFocus(); + test_endSession(); + test_FindClosestCategory(); + test_Disable(); + test_ThreadMgrUnadviseSinks(); + test_UnregisterCategory(); + test_Unregister(); + } + else + skip("Unable to create InputProcessor\n"); + cleanup(); } diff --git a/rostests/winetests/mshtml/dom.c b/rostests/winetests/mshtml/dom.c index 25bf7641eb1..c6f54793ce5 100644 --- a/rostests/winetests/mshtml/dom.c +++ b/rostests/winetests/mshtml/dom.c @@ -3173,6 +3173,16 @@ static void test_navigator(IHTMLDocument2 *doc) ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf); SysFreeString(bstr); + if(!strncmp(buf, "Mozilla/", 8)) { + bstr = NULL; + hres = IOmNavigator_get_appVersion(navigator, &bstr); + ok(hres == S_OK, "get_appVersion failed: %08x\n", hres); + ok(!strcmp_wa(bstr, buf+8), "appVersion returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf+8); + SysFreeString(bstr); + }else { + skip("nonstandard user agent\n"); + } + ref = IOmNavigator_Release(navigator); ok(!ref, "navigator should be destroyed here\n"); } @@ -3185,8 +3195,6 @@ static void test_screen(IHTMLWindow2 *window) HDC hdc; HRESULT hres; - static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0}; - screen = NULL; hres = IHTMLWindow2_get_screen(window, &screen); ok(hres == S_OK, "get_screen failed: %08x\n", hres); @@ -3206,7 +3214,7 @@ static void test_screen(IHTMLWindow2 *window) IDispatchEx_Release(dispex); } - hdc = CreateICW(displayW, NULL, NULL, NULL); + hdc = CreateICA("DISPLAY", NULL, NULL, NULL); exl = GetDeviceCaps(hdc, HORZRES); l = 0xdeadbeef; diff --git a/rostests/winetests/mshtml/events.c b/rostests/winetests/mshtml/events.c index 16f727fdec7..d62df7a3b0b 100644 --- a/rostests/winetests/mshtml/events.c +++ b/rostests/winetests/mshtml/events.c @@ -67,6 +67,8 @@ DEFINE_EXPECT(div_onclick_disp); DEFINE_EXPECT(iframe_onreadystatechange_loading); DEFINE_EXPECT(iframe_onreadystatechange_interactive); DEFINE_EXPECT(iframe_onreadystatechange_complete); +DEFINE_EXPECT(iframedoc_onreadystatechange); +DEFINE_EXPECT(img_onload); static HWND container_hwnd = NULL; static IHTMLWindow2 *window; @@ -92,7 +94,10 @@ static const char click_doc_str[] = ""; static const char readystate_doc_str[] = - "<"; + ""; + +static const char img_doc_str[] = + ""; static const char *debugstr_guid(REFIID riid) { @@ -879,14 +884,46 @@ static HRESULT WINAPI body_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WOR EVENT_HANDLER_FUNC_OBJ(body_onclick); +static HRESULT WINAPI img_onload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + CHECK_EXPECT(img_onload); + test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_src("IMG"); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(img_onload); + +static HRESULT WINAPI iframedoc_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + IHTMLEventObj *event = NULL; + HRESULT hres; + + CHECK_EXPECT2(iframedoc_onreadystatechange); + test_event_args(&DIID_DispHTMLDocument, id, wFlags, pdp, pvarRes, pei, pspCaller); + + event = (void*)0xdeadbeef; + hres = IHTMLWindow2_get_event(window, &event); + ok(hres == S_OK, "get_event failed: %08x\n", hres); + ok(!event, "event = %p\n", event); + + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(iframedoc_onreadystatechange); + static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { + IHTMLWindow2 *iframe_window; + IHTMLDocument2 *iframe_doc; IHTMLFrameBase2 *iframe; IHTMLElement2 *elem2; IHTMLElement *elem; VARIANT v; - BSTR str; + BSTR str, str2; HRESULT hres; test_event_args(&DIID_DispHTMLIFrame, id, wFlags, pdp, pvarRes, pei, pspCaller); @@ -913,15 +950,33 @@ static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, L ok(!lstrcmpW(str, V_BSTR(&v)), "ready states differ\n"); VariantClear(&v); - if(!strcmp_wa(str, "loading")) + hres = IHTMLFrameBase2_get_contentWindow(iframe, &iframe_window); + ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres); + + hres = IHTMLWindow2_get_document(iframe_window, &iframe_doc); + IHTMLWindow2_Release(iframe_window); + ok(hres == S_OK, "get_document failed: %08x\n", hres); + + hres = IHTMLDocument2_get_readyState(iframe_doc, &str2); + ok(!lstrcmpW(str, str2), "unexpected document readyState %s\n", wine_dbgstr_w(str2)); + SysFreeString(str2); + + if(!strcmp_wa(str, "loading")) { CHECK_EXPECT(iframe_onreadystatechange_loading); - else if(!strcmp_wa(str, "interactive")) + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&iframedoc_onreadystatechange_obj; + hres = IHTMLDocument2_put_onreadystatechange(iframe_doc, v); + ok(hres == S_OK, "put_onreadystatechange: %08x\n", hres); + }else if(!strcmp_wa(str, "interactive")) CHECK_EXPECT(iframe_onreadystatechange_interactive); else if(!strcmp_wa(str, "complete")) CHECK_EXPECT(iframe_onreadystatechange_complete); else ok(0, "unexpected state %s\n", wine_dbgstr_w(str)); + IHTMLDocument2_Release(iframe_doc); + IHTMLFrameBase2_Release(iframe); return S_OK; } @@ -1307,17 +1362,60 @@ static void test_onreadystatechange(IHTMLDocument2 *doc) ok(hres == S_OK, "put_src failed: %08x\n", hres); SET_EXPECT(iframe_onreadystatechange_loading); + SET_EXPECT(iframedoc_onreadystatechange); SET_EXPECT(iframe_onreadystatechange_interactive); SET_EXPECT(iframe_onreadystatechange_complete); pump_msgs(&called_iframe_onreadystatechange_complete); - todo_wine CHECK_CALLED(iframe_onreadystatechange_loading); + CHECK_CALLED(iframedoc_onreadystatechange); CHECK_CALLED(iframe_onreadystatechange_interactive); CHECK_CALLED(iframe_onreadystatechange_complete); IHTMLFrameBase_Release(iframe); } +static void test_imgload(IHTMLDocument2 *doc) +{ + IHTMLImgElement *img; + IHTMLElement *elem; + VARIANT v; + BSTR str; + HRESULT hres; + + elem = get_elem_id(doc, "imgid"); + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLImgElement, (void**)&img); + IHTMLElement_Release(elem); + ok(hres == S_OK, "Could not get IHTMLImgElement iface: %08x\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLImgElement_get_onload(img, &v); + ok(hres == S_OK, "get_onload failed: %08x\n", hres); + ok(V_VT(&v) == VT_NULL, "V_VT(onload) = %d\n", V_VT(&v)); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&img_onload_obj; + hres = IHTMLImgElement_put_onload(img, v); + ok(hres == S_OK, "put_onload failed: %08x\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLImgElement_get_onload(img, &v); + ok(hres == S_OK, "get_onload failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(onload) = %d\n", V_VT(&v)); + ok(V_DISPATCH(&v) == (IDispatch*)&img_onload_obj, "V_DISPATCH(onload) != onloadkFunc\n"); + VariantClear(&v); + + str = a2bstr("http://www.winehq.org/images/winehq_logo_text.png"); + hres = IHTMLImgElement_put_src(img, str); + ok(hres == S_OK, "put_src failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(img_onload); + pump_msgs(&called_img_onload); + CHECK_CALLED(img_onload); + + IHTMLImgElement_Release(img); +} + static void test_timeout(IHTMLDocument2 *doc) { IHTMLWindow3 *win3; @@ -1957,6 +2055,7 @@ START_TEST(events) run_test(empty_doc_str, test_timeout); run_test(click_doc_str, test_onclick); run_test(readystate_doc_str, test_onreadystatechange); + run_test(img_doc_str, test_imgload); DestroyWindow(container_hwnd); CoUninitialize(); diff --git a/rostests/winetests/mshtml/jstest.html b/rostests/winetests/mshtml/jstest.html index 72ef427485a..6192f815af3 100644 --- a/rostests/winetests/mshtml/jstest.html +++ b/rostests/winetests/mshtml/jstest.html @@ -5,12 +5,30 @@ function ok(b,m) { return external.ok(b, m); } +function test_removeAttribute(e) { + ok(e.removeAttribute('nonexisting') === false, "removeAttribute('nonexisting') didn't return false"); + + e.title = "title"; + ok(e.removeAttribute('title') === true, "removeAttribute('title') didn't return true"); + ok(e.title === "", "e.title = " + e.title); + ok(("title" in e) === true, "title is not in e"); + + e["myattr"] = "test"; + ok(e.removeAttribute('myattr') === true, "removeAttribute('myattr') didn't return true"); + ok(e["myattr"] === undefined, "e['myattr'] = " + e['myattr']); + ok(("myattr" in e) === false, "myattr is in e"); + +} + function runTest() { obj = new Object(); ok(obj === window.obj, "obj !== window.obj"); ok(typeof(divid) === "object", "typeof(divid) = " + typeof(divid)); + test_removeAttribute(document.getElementById("divid")); + test_removeAttribute(document.body); + external.reportSuccess(); } diff --git a/rostests/winetests/mshtml/script.c b/rostests/winetests/mshtml/script.c index 6a0cbe36906..56d83efa696 100644 --- a/rostests/winetests/mshtml/script.c +++ b/rostests/winetests/mshtml/script.c @@ -1050,12 +1050,22 @@ static HRESULT QueryInterface(REFIID riid, void **ppv) static IHTMLDocument2 *create_document(void) { IHTMLDocument2 *doc; + IHTMLDocument5 *doc5; HRESULT hres; hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IHTMLDocument2, (void**)&doc); ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres); + if (hres != S_OK) return NULL; + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5); + if(FAILED(hres)) { + win_skip("Could not get IHTMLDocument5, probably too old IE\n"); + IHTMLDocument2_Release(doc); + return NULL; + } + + IHTMLDocument5_Release(doc5); return doc; } diff --git a/rostests/winetests/msxml3/domdoc.c b/rostests/winetests/msxml3/domdoc.c index 5f06d93f381..a743e51d391 100644 --- a/rostests/winetests/msxml3/domdoc.c +++ b/rostests/winetests/msxml3/domdoc.c @@ -535,6 +535,7 @@ static void test_domdoc( void ) BSTR str; LONG code; LONG nLength = 0; + WCHAR buff[100]; r = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc ); @@ -543,6 +544,12 @@ static void test_domdoc( void ) test_disp((IUnknown*)doc); +if (0) +{ + /* crashes on native */ + r = IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL ); +} + /* try some stupid things */ r = IXMLDOMDocument_loadXML( doc, NULL, NULL ); ok( r == S_FALSE, "loadXML failed\n"); @@ -601,6 +608,15 @@ static void test_domdoc( void ) ok( r == S_FALSE, "should be no document element\n"); ok( element == NULL, "Element should be NULL\n"); + /* test for BSTR handling, pass broken BSTR */ + memcpy(&buff[2], szComplete1, sizeof(szComplete1)); + /* just a big length */ + *(DWORD*)buff = 0xf0f0; + b = VARIANT_FALSE; + r = IXMLDOMDocument_loadXML( doc, &buff[2], &b ); + ok( r == S_OK, "loadXML failed\n"); + ok( b == VARIANT_TRUE, "failed to load XML string\n"); + /* try to load something valid */ b = VARIANT_FALSE; str = SysAllocString( szComplete1 ); @@ -2734,6 +2750,12 @@ static void test_XMLHTTP(void) SysFreeString(str2); hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody); + if (hr == INET_E_RESOURCE_NOT_FOUND) + { + skip("No connection could be made with crossover.codeweavers.com\n"); + IXMLHttpRequest_Release(pXMLHttpRequest); + return; + } todo_wine ok(hr == S_OK, "IXMLHttpRequest_send should have succeeded instead of failing with 0x%08x\n", hr); VariantClear(&varbody); diff --git a/rostests/winetests/rsaenh/rsaenh.c b/rostests/winetests/rsaenh/rsaenh.c index 83ec87252c1..cb560f21e0e 100644 --- a/rostests/winetests/rsaenh/rsaenh.c +++ b/rostests/winetests/rsaenh/rsaenh.c @@ -128,16 +128,28 @@ static int init_base_environment(DWORD dwKeyFlags) hProv = (HCRYPTPROV)INVALID_HANDLE_VALUE; result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError()); + ok(!result && (GetLastError()==NTE_BAD_FLAGS || + broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */)), + "%d, %08x\n", result, GetLastError()); if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0)) { - ok(GetLastError()==NTE_BAD_KEYSET, "%08x\n", GetLastError()); - if (GetLastError()!=NTE_BAD_KEYSET) return 0; + ok(GetLastError()==NTE_BAD_KEYSET || + broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */), + "%08x\n", GetLastError()); + if (GetLastError()!=NTE_BAD_KEYSET) + { + win_skip("RSA full provider not available\n"); + return 0; + } result = CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, CRYPT_NEWKEYSET); ok(result, "%08x\n", GetLastError()); - if (!result) return 0; + if (!result) + { + win_skip("Couldn't create crypto provider\n"); + return 0; + } result = CryptGenKey(hProv, AT_KEYEXCHANGE, dwKeyFlags, &hKey); ok(result, "%08x\n", GetLastError()); if (result) CryptDestroyKey(hKey); @@ -275,7 +287,6 @@ static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len) return FALSE; } ok(result, "%08x\n", GetLastError()); - if (!result) return FALSE; result = CryptHashData(hHash, pbData, sizeof(pbData), 0); ok(result, "%08x\n", GetLastError()); if (!result) return FALSE; @@ -309,8 +320,9 @@ static void test_hashes(void) unsigned char pbData[2048]; BOOL result; HCRYPTHASH hHash, hHashClone; + HCRYPTPROV prov; BYTE pbHashValue[36]; - DWORD hashlen, len; + DWORD hashlen, len, error; int i; for (i=0; i<2048; i++) pbData[i] = (unsigned char)i; @@ -441,6 +453,74 @@ static void test_hashes(void) result = CryptDestroyHash(hHash); ok(result, "%08x\n", GetLastError()); + + /* The SHA-2 variants aren't supported in the RSA full provider */ + result = CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash); + ok(!result && GetLastError() == NTE_BAD_ALGID, + "expected NTE_BAD_ALGID, got %08x\n", GetLastError()); + result = CryptCreateHash(hProv, CALG_SHA_384, 0, 0, &hHash); + ok(!result && GetLastError() == NTE_BAD_ALGID, + "expected NTE_BAD_ALGID, got %08x\n", GetLastError()); + result = CryptCreateHash(hProv, CALG_SHA_512, 0, 0, &hHash); + ok(!result && GetLastError() == NTE_BAD_ALGID, + "expected NTE_BAD_ALGID, got %08x\n", GetLastError()); + + result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError()); + + result = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hHash); + ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError()); + + /* release provider before using the hash */ + result = CryptReleaseContext(prov, 0); + ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0); + error = GetLastError(); + ok(!result, "CryptHashData succeeded\n"); + ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); + + SetLastError(0xdeadbeef); + result = CryptDestroyHash(hHash); + error = GetLastError(); + ok(!result, "CryptDestroyHash succeeded\n"); + ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); + + if (!pCryptDuplicateHash) + { + win_skip("CryptDuplicateHash is not available\n"); + return; + } + + result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError()); + + result = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash); + ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError()); + + result = CryptHashData(hHash, (const BYTE *)"data", sizeof("data"), 0); + ok(result, "CryptHashData failed 0x%08x\n", GetLastError()); + + result = pCryptDuplicateHash(hHash, NULL, 0, &hHashClone); + ok(result, "CryptDuplicateHash failed 0x%08x\n", GetLastError()); + + len = 20; + result = CryptGetHashParam(hHashClone, HP_HASHVAL, pbHashValue, &len, 0); + ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError()); + + /* add data after duplicating the hash */ + result = CryptHashData(hHash, (const BYTE *)"more data", sizeof("more data"), 0); + ok(result, "CryptHashData failed 0x%08x\n", GetLastError()); + + result = CryptDestroyHash(hHash); + ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError()); + + result = CryptDestroyHash(hHashClone); + ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError()); + + result = CryptReleaseContext(prov, 0); + ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError()); } static void test_block_cipher_modes(void) @@ -471,6 +551,10 @@ static void test_block_cipher_modes(void) result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0); ok(result, "%08x\n", GetLastError()); + result = CryptGetKeyParam(hKey, KP_SALT, NULL, &dwLen, 0); + ok(result, "%08x\n", GetLastError()); + ok(dwLen == 11 || broken(dwLen == 0 /* Win9x/NT4 */), "unexpected salt length %d\n", dwLen); + dwLen = 23; result = CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 24); ok(result, "CryptEncrypt failed: %08x\n", GetLastError()); @@ -716,6 +800,11 @@ static void test_aes(int keylen) for (i=0; iInitialize == (void *) pNextTable->FreeCredentialsHandle && + pNextTable->FreeCredentialsHandle != NULL)) + { + win_skip("Invalid function pointers for next package\n"); + return NULL; + } + + return pNextTable; } static void testGetInfo(void) @@ -181,7 +208,9 @@ static void testGetInfo(void) PackageInfo.fCapabilities); ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion); ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID); - ok(PackageInfo.cbMaxToken == 0x4000, "cbMaxToken: 0x%x\n", + ok(PackageInfo.cbMaxToken == 0x4000 || + PackageInfo.cbMaxToken == 0x6000, /* Win7 */ + "cbMaxToken: 0x%x\n", PackageInfo.cbMaxToken); } } diff --git a/rostests/winetests/shlwapi/generated.c b/rostests/winetests/shlwapi/generated.c index db44d275994..e5e0896af8f 100755 --- a/rostests/winetests/shlwapi/generated.c +++ b/rostests/winetests/shlwapi/generated.c @@ -56,41 +56,102 @@ * Test helper macros */ -#ifdef _WIN64 +#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); -# define TEST_TYPE_SIZE(type, size) +#ifdef TYPE_ALIGNMENT +# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); +#else # define TEST_TYPE_ALIGN(type, align) +#endif + +#ifdef _TYPE_ALIGNMENT +# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); +# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); +#else # define TEST_TARGET_ALIGN(type, align) # define TEST_FIELD_ALIGN(type, field, align) -# define TEST_FIELD_OFFSET(type, field, offset) +#endif -#else +#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); -# define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); +#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) +#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) +#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); +#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); -# ifdef TYPE_ALIGNMENT -# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); -# else -# define TEST_TYPE_ALIGN(type, align) -# endif -# ifdef _TYPE_ALIGNMENT -# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); -# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); -# else -# define TEST_TARGET_ALIGN(type, align) -# define TEST_FIELD_ALIGN(type, field, align) -# endif +#ifdef _WIN64 -# define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); +static void test_pack_ASSOCF(void) +{ + /* ASSOCF */ + TEST_TYPE_SIZE (ASSOCF, 4) + TEST_TYPE_ALIGN (ASSOCF, 4) + TEST_TYPE_UNSIGNED(ASSOCF) +} -#endif +static void test_pack_DLLGETVERSIONPROC(void) +{ + /* DLLGETVERSIONPROC */ + TEST_TYPE_SIZE (DLLGETVERSIONPROC, 8) + TEST_TYPE_ALIGN (DLLGETVERSIONPROC, 8) +} -#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) -#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) -#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); -#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); +static void test_pack_DLLVERSIONINFO(void) +{ + /* DLLVERSIONINFO (pack 8) */ + TEST_TYPE_SIZE (DLLVERSIONINFO, 20) + TEST_TYPE_ALIGN (DLLVERSIONINFO, 4) + TEST_FIELD_SIZE (DLLVERSIONINFO, cbSize, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO, cbSize, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO, cbSize, 0) + TEST_FIELD_SIZE (DLLVERSIONINFO, dwMajorVersion, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO, dwMajorVersion, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO, dwMajorVersion, 4) + TEST_FIELD_SIZE (DLLVERSIONINFO, dwMinorVersion, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO, dwMinorVersion, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO, dwMinorVersion, 8) + TEST_FIELD_SIZE (DLLVERSIONINFO, dwBuildNumber, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO, dwBuildNumber, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO, dwBuildNumber, 12) + TEST_FIELD_SIZE (DLLVERSIONINFO, dwPlatformID, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO, dwPlatformID, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO, dwPlatformID, 16) +} +static void test_pack_DLLVERSIONINFO2(void) +{ + /* DLLVERSIONINFO2 (pack 8) */ + TEST_TYPE_SIZE (DLLVERSIONINFO2, 32) + TEST_TYPE_ALIGN (DLLVERSIONINFO2, 8) + TEST_FIELD_SIZE (DLLVERSIONINFO2, info1, 20) + TEST_FIELD_ALIGN (DLLVERSIONINFO2, info1, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO2, info1, 0) + TEST_FIELD_SIZE (DLLVERSIONINFO2, dwFlags, 4) + TEST_FIELD_ALIGN (DLLVERSIONINFO2, dwFlags, 4) + TEST_FIELD_OFFSET(DLLVERSIONINFO2, dwFlags, 20) + TEST_FIELD_SIZE (DLLVERSIONINFO2, ullVersion, 8) + TEST_FIELD_ALIGN (DLLVERSIONINFO2, ullVersion, 8) + TEST_FIELD_OFFSET(DLLVERSIONINFO2, ullVersion, 24) +} + +static void test_pack_HUSKEY(void) +{ + /* HUSKEY */ + TEST_TYPE_SIZE (HUSKEY, 8) + TEST_TYPE_ALIGN (HUSKEY, 8) +} + +static void test_pack_PHUSKEY(void) +{ + /* PHUSKEY */ + TEST_TYPE_SIZE (PHUSKEY, 8) + TEST_TYPE_ALIGN (PHUSKEY, 8) + TEST_TARGET_SIZE (PHUSKEY, 8) + TEST_TARGET_ALIGN(PHUSKEY, 8) +} + +#else /* _WIN64 */ static void test_pack_ASSOCF(void) { @@ -161,6 +222,8 @@ static void test_pack_PHUSKEY(void) TEST_TARGET_ALIGN(PHUSKEY, 4) } +#endif /* _WIN64 */ + static void test_pack(void) { test_pack_ASSOCF(); @@ -173,9 +236,5 @@ static void test_pack(void) START_TEST(generated) { -#ifdef _WIN64 - ok(0, "The type size / alignment tests don't support Win64 yet\n"); -#else test_pack(); -#endif } diff --git a/rostests/winetests/shlwapi/istream.c b/rostests/winetests/shlwapi/istream.c index 67d1fe25182..4a36b3ab0ba 100644 --- a/rostests/winetests/shlwapi/istream.c +++ b/rostests/winetests/shlwapi/istream.c @@ -208,12 +208,16 @@ static void test_SHCreateStreamOnFileA(DWORD mode, DWORD stgm) /* invalid arguments */ stream = NULL; - /* NT: ERROR_PATH_NOT_FOUND, 9x: ERROR_BAD_PATHNAME */ ret = (*pSHCreateStreamOnFileA)(NULL, mode | stgm, &stream); - ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || - ret == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), - "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)" - "or HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), got 0x%08x\n", ret); + if (ret == E_INVALIDARG) /* Win98 SE */ { + win_skip("Not supported\n"); + return; + } + + ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) /* NT */ || + ret == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME) /* 9x */, + "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) " + "or HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), got 0x%08x\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); #if 0 /* This test crashes on WinXP SP2 */ @@ -342,6 +346,11 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) stream = NULL; ret = (*pSHCreateStreamOnFileW)(test_file, mode | STGM_FAILIFTHERE | stgm, &stream); + if (ret == E_INVALIDARG) /* Win98 SE */ { + win_skip("Not supported\n"); + return; + } + ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); @@ -423,6 +432,11 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) stream = NULL; ret = (*pSHCreateStreamOnFileEx)(test_file, mode, 0, FALSE, template, &stream); + if (ret == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { + win_skip("File probably locked by Anti-Virus/Spam software, trying again\n"); + Sleep(1000); + ret = (*pSHCreateStreamOnFileEx)(test_file, mode, 0, FALSE, template, &stream); + } ok( ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || ret == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) or " @@ -482,6 +496,11 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) stream = NULL; ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream); + if (ret == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { + win_skip("File probably locked by Anti-Virus/Spam software, trying again\n"); + Sleep(1000); + ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream); + } ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); @@ -498,6 +517,11 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) stream = NULL; ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream); + if (ret == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { + win_skip("File probably locked by Anti-Virus/Spam software, trying again\n"); + Sleep(1000); + ret = (*pSHCreateStreamOnFileEx)(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream); + } ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); diff --git a/rostests/winetests/shlwapi/ordinal.c b/rostests/winetests/shlwapi/ordinal.c index 22437e2b17a..cfc25e116c7 100755 --- a/rostests/winetests/shlwapi/ordinal.c +++ b/rostests/winetests/shlwapi/ordinal.c @@ -28,9 +28,14 @@ #include "oaidl.h" #include "ocidl.h" #include "mlang.h" +#include "shlwapi.h" +#include "docobj.h" +#include "shobjidl.h" /* Function ptrs for ordinal calls */ static HMODULE hShlwapi; +static BOOL is_win2k_and_lower; + static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int); static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD); @@ -43,6 +48,14 @@ static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID, static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD); static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **); static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG); +static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT); +static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT); +static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT); +static DWORD (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*); +static BOOL (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *); +static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUID*, DWORD, DWORD, VARIANT*, VARIANT*); +static HRESULT (WINAPI *pIUnknown_ProfferService)(IUnknown*, REFGUID, IServiceProvider*, DWORD*); +static HWND (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU, LONG_PTR); static HMODULE hmlang; static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT); @@ -55,6 +68,79 @@ static const CHAR ie_international[] = { static const CHAR acceptlanguage[] = { 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0}; +typedef struct { + int id; + const void *args[5]; +} call_entry_t; + +typedef struct { + call_entry_t *calls; + int count; + int alloc; +} call_trace_t; + +static void init_call_trace(call_trace_t *ctrace) +{ + ctrace->alloc = 10; + ctrace->count = 0; + ctrace->calls = HeapAlloc(GetProcessHeap(), 0, sizeof(call_entry_t) * ctrace->alloc); +} + +static void free_call_trace(const call_trace_t *ctrace) +{ + HeapFree(GetProcessHeap(), 0, ctrace->calls); +} + +static void add_call(call_trace_t *ctrace, int id, const void *arg0, + const void *arg1, const void *arg2, const void *arg3, const void *arg4) +{ + call_entry_t call; + + call.id = id; + call.args[0] = arg0; + call.args[1] = arg1; + call.args[2] = arg2; + call.args[3] = arg3; + call.args[4] = arg4; + + if (ctrace->count == ctrace->alloc) + { + ctrace->alloc *= 2; + ctrace->calls = HeapReAlloc(GetProcessHeap(),0, ctrace->calls, ctrace->alloc*sizeof(call_entry_t)); + } + + ctrace->calls[ctrace->count++] = call; +} + +static void ok_trace_(call_trace_t *texpected, call_trace_t *tgot, int line) +{ + if (texpected->count == tgot->count) + { + INT i; + /* compare */ + for (i = 0; i < texpected->count; i++) + { + call_entry_t *expected = &texpected->calls[i]; + call_entry_t *got = &tgot->calls[i]; + INT j; + + ok_(__FILE__, line)(expected->id == got->id, "got different ids %d: %d, %d\n", i+1, expected->id, got->id); + + for (j = 0; j < 5; j++) + { + ok_(__FILE__, line)(expected->args[j] == got->args[j], "got different args[%d] for %d: %p, %p\n", j, i+1, + expected->args[j], got->args[j]); + } + } + } + else + ok_(__FILE__, line)(0, "traces length mismatch\n"); +} + +#define ok_trace(a, b) ok_trace_(a, b, __LINE__) + +/* trace of actually made calls */ +static call_trace_t trace_got; static void test_GetAcceptLanguagesA(void) { @@ -180,7 +266,7 @@ static void test_GetAcceptLanguagesA(void) /* There is no space for the string in the registry. When the buffer is large enough, the default language is returned - When the buffer is to small for that fallback, win7_32 and w2k8_64 + When the buffer is too small for that fallback, win7_32 and w2k8_64 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but recent os succeed and return a partial result while older os succeed and overflow the buffer */ @@ -248,7 +334,7 @@ static void test_GetAcceptLanguagesA(void) memset(buffer, '#', maxlen); buffer[maxlen] = 0; hr = pGetAcceptLanguagesA( buffer, &len); - /* When the buffer is to small, win7_32 and w2k8_64 and above fail with + /* When the buffer is too small, win7_32 and w2k8_64 and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed and return a partial 0 terminated result while other versions fail with E_INVALIDARG and return a partial unterminated result */ @@ -1397,31 +1483,940 @@ static void test_SHPropertyBag_ReadLONG(void) IUnknown_Release((IUnknown*)pb); } + + +static void test_SHSetWindowBits(void) +{ + HWND hwnd; + DWORD style, styleold; + WNDCLASSA clsA; + + if(!pSHSetWindowBits) + { + win_skip("SHSetWindowBits is not available\n"); + return; + } + + clsA.style = 0; + clsA.lpfnWndProc = DefWindowProcA; + clsA.cbClsExtra = 0; + clsA.cbWndExtra = 0; + clsA.hInstance = GetModuleHandleA(NULL); + clsA.hIcon = 0; + clsA.hCursor = LoadCursorA(0, IDC_ARROW); + clsA.hbrBackground = NULL; + clsA.lpszMenuName = NULL; + clsA.lpszClassName = "Shlwapi test class"; + RegisterClassA(&clsA); + + hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100, + NULL, NULL, GetModuleHandle(NULL), 0); + ok(IsWindow(hwnd), "failed to create window\n"); + + /* null window */ + SetLastError(0xdeadbeef); + style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0); + ok(style == 0, "expected 0 retval, got %d\n", style); + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || + broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */ + "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError()); + + /* zero mask, zero flags */ + styleold = GetWindowLongA(hwnd, GWL_STYLE); + style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0); + ok(styleold == style, "expected old style\n"); + ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n"); + + /* test mask */ + styleold = GetWindowLongA(hwnd, GWL_STYLE); + ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n"); + style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0); + + ok(style == styleold, "expected previous style, got %x\n", style); + ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); + + /* test mask, unset style bit used */ + styleold = GetWindowLongA(hwnd, GWL_STYLE); + style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0); + ok(style == styleold, "expected previous style, got %x\n", style); + ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n"); + + /* set back with flags */ + styleold = GetWindowLongA(hwnd, GWL_STYLE); + style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE); + ok(style == styleold, "expected previous style, got %x\n", style); + ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n"); + + /* reset and try to set without a mask */ + pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0); + ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); + styleold = GetWindowLongA(hwnd, GWL_STYLE); + style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE); + ok(style == styleold, "expected previous style, got %x\n", style); + ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); + + DestroyWindow(hwnd); + + UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL)); +} + +static void test_SHFormatDateTimeA(void) +{ + FILETIME UNALIGNED filetime; + CHAR buff[100], buff2[100], buff3[100]; + SYSTEMTIME st; + DWORD flags; + INT ret; + + if(!pSHFormatDateTimeA) + { + win_skip("pSHFormatDateTimeA isn't available\n"); + return; + } + +if (0) +{ + /* crashes on native */ + ret = pSHFormatDateTimeA(NULL, NULL, NULL, 0); +} + + GetLocalTime(&st); + SystemTimeToFileTime(&st, &filetime); + /* SHFormatDateTime expects input as utc */ + LocalFileTimeToFileTime(&filetime, &filetime); + + /* no way to get required buffer length here */ + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0); + ok(ret == 0, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + buff[0] = 'a'; buff[1] = 0; + ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0); + ok(ret == 0, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(buff[0] == 'a', "expected same string, got %s\n", buff); + + /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */ + + /* all combinations documented as invalid succeeded */ + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME | FDTF_LONGTIME; + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGDATE; + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE; + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef || + broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */ + "expected 0xdeadbeef, got %d\n", GetLastError()); + + /* now check returned strings */ + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + /* both time flags */ + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME | FDTF_SHORTTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + /* both date flags */ + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTDATE; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + /* various combinations of date/time flags */ + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + strcat(buff2, ", "); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)); + ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); + strcat(buff2, buff3); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_LONGTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + strcat(buff2, ", "); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)); + ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); + strcat(buff2, buff3); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_SHORTTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + strcat(buff2, " "); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)); + ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); + strcat(buff2, buff3); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + + flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + strcat(buff2, " "); + ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)); + ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); + strcat(buff2, buff3); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); +} + +static void test_SHFormatDateTimeW(void) +{ + FILETIME UNALIGNED filetime; + WCHAR buff[100], buff2[100], buff3[100]; + SYSTEMTIME st; + DWORD flags; + INT ret; + static const WCHAR spaceW[] = {' ',0}; + static const WCHAR commaW[] = {',',' ',0}; + + if(!pSHFormatDateTimeW) + { + win_skip("pSHFormatDateTimeW isn't available\n"); + return; + } + +if (0) +{ + /* crashes on native */ + ret = pSHFormatDateTimeW(NULL, NULL, NULL, 0); +} + + GetLocalTime(&st); + SystemTimeToFileTime(&st, &filetime); + /* SHFormatDateTime expects input as utc */ + LocalFileTimeToFileTime(&filetime, &filetime); + + /* no way to get required buffer length here */ + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0); + ok(ret == 0, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + buff[0] = 'a'; buff[1] = 0; + ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0); + ok(ret == 0, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(buff[0] == 'a', "expected same string\n"); + + /* all combinations documented as invalid succeeded */ + flags = FDTF_SHORTTIME | FDTF_LONGTIME; + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + flags = FDTF_SHORTDATE | FDTF_LONGDATE; + SetLastError(0xdeadbeef); + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + + flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE; + SetLastError(0xdeadbeef); + buff[0] = 0; /* NT4 doesn't clear the buffer on failure */ + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef || + broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe/NT4 */ + "expected 0xdeadbeef, got %d\n", GetLastError()); + + /* now check returned strings */ + flags = FDTF_SHORTTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + SetLastError(0xdeadbeef); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Needed W-functions are not implemented\n"); + return; + } + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + flags = FDTF_LONGTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + /* both time flags */ + flags = FDTF_LONGTIME | FDTF_SHORTTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n"); + + flags = FDTF_SHORTDATE; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + flags = FDTF_LONGDATE; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + /* both date flags */ + flags = FDTF_LONGDATE | FDTF_SHORTDATE; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + /* various combinations of date/time flags */ + flags = FDTF_LONGDATE | FDTF_SHORTTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d, length %d\n", ret, lstrlenW(buff)+1); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + lstrcatW(buff2, commaW); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff3)+1, "got %d\n", ret); + lstrcatW(buff2, buff3); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + flags = FDTF_LONGDATE | FDTF_LONGTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + lstrcatW(buff2, commaW); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff3)+1, "got %d\n", ret); + lstrcatW(buff2, buff3); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + flags = FDTF_SHORTDATE | FDTF_SHORTTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + lstrcatW(buff2, spaceW); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff3)+1, "got %d\n", ret); + lstrcatW(buff2, buff3); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); + + flags = FDTF_SHORTDATE | FDTF_LONGTIME; + ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff)+1, "got %d\n", ret); + ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff2)+1, "got %d\n", ret); + lstrcatW(buff2, spaceW); + ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR)); + ok(ret == lstrlenW(buff3)+1, "got %d\n", ret); + lstrcatW(buff2, buff3); + ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n"); +} + +static void test_SHGetObjectCompatFlags(void) +{ + struct compat_value { + CHAR nameA[30]; + DWORD value; + }; + + struct compat_value values[] = { + { "OTNEEDSSFCACHE", 0x1 }, + { "NO_WEBVIEW", 0x2 }, + { "UNBINDABLE", 0x4 }, + { "PINDLL", 0x8 }, + { "NEEDSFILESYSANCESTOR", 0x10 }, + { "NOTAFILESYSTEM", 0x20 }, + { "CTXMENU_NOVERBS", 0x40 }, + { "CTXMENU_LIMITEDQI", 0x80 }, + { "COCREATESHELLFOLDERONLY", 0x100 }, + { "NEEDSSTORAGEANCESTOR", 0x200 }, + { "NOLEGACYWEBVIEW", 0x400 }, + { "CTXMENU_XPQCMFLAGS", 0x1000 }, + { "NOIPROPERTYSTORE", 0x2000 } + }; + + static const char compat_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects"; + CHAR keyA[39]; /* {CLSID} */ + HKEY root; + DWORD ret; + int i; + + if (!pSHGetObjectCompatFlags) + { + win_skip("SHGetObjectCompatFlags isn't available\n"); + return; + } + + /* null args */ + ret = pSHGetObjectCompatFlags(NULL, NULL); + ok(ret == 0, "got %d\n", ret); + + ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root); + if (ret != ERROR_SUCCESS) + { + skip("No compatibility class data found\n"); + return; + } + + for (i = 0; RegEnumKeyA(root, i, keyA, sizeof(keyA)) == ERROR_SUCCESS; i++) + { + HKEY clsid_key; + + if (RegOpenKeyA(root, keyA, &clsid_key) == ERROR_SUCCESS) + { + CHAR valueA[30]; + DWORD expected = 0, got, length = sizeof(valueA); + CLSID clsid; + int v; + + for (v = 0; RegEnumValueA(clsid_key, v, valueA, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; v++) + { + int j; + + for (j = 0; j < sizeof(values)/sizeof(struct compat_value); j++) + if (lstrcmpA(values[j].nameA, valueA) == 0) + { + expected |= values[j].value; + break; + } + + length = sizeof(valueA); + } + + pGUIDFromStringA(keyA, &clsid); + got = pSHGetObjectCompatFlags(NULL, &clsid); + ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA); + + RegCloseKey(clsid_key); + } + } + + RegCloseKey(root); +} + +typedef struct { + const IOleCommandTargetVtbl *lpVtbl; + LONG ref; +} IOleCommandTargetImpl; + +static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl; + +IOleCommandTarget* IOleCommandTargetImpl_Construct(void) +{ + IOleCommandTargetImpl *obj; + + obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); + obj->lpVtbl = &IOleCommandTargetImpl_Vtbl; + obj->ref = 1; + + return (IOleCommandTarget*)obj; +} + +static HRESULT WINAPI IOleCommandTargetImpl_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppvObj) +{ + IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IOleCommandTarget)) + { + *ppvObj = This; + } + + if(*ppvObj) + { + IUnknown_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI IOleCommandTargetImpl_AddRef(IOleCommandTarget *iface) +{ + IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI IOleCommandTargetImpl_Release(IOleCommandTarget *iface) +{ + IOleCommandTargetImpl *This = (IOleCommandTargetImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + return 0; + } + return ref; +} + +static HRESULT WINAPI IOleCommandTargetImpl_QueryStatus( + IOleCommandTarget *iface, const GUID *group, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI IOleCommandTargetImpl_Exec( + IOleCommandTarget *iface, + const GUID *CmdGroup, + DWORD nCmdID, + DWORD nCmdexecopt, + VARIANT *pvaIn, + VARIANT *pvaOut) +{ + add_call(&trace_got, 3, CmdGroup, (void*)(DWORD_PTR)nCmdID, (void*)(DWORD_PTR)nCmdexecopt, pvaIn, pvaOut); + return S_OK; +} + +static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl = +{ + IOleCommandTargetImpl_QueryInterface, + IOleCommandTargetImpl_AddRef, + IOleCommandTargetImpl_Release, + IOleCommandTargetImpl_QueryStatus, + IOleCommandTargetImpl_Exec +}; + +typedef struct { + const IServiceProviderVtbl *lpVtbl; + LONG ref; +} IServiceProviderImpl; + +typedef struct { + const IProfferServiceVtbl *lpVtbl; + LONG ref; +} IProfferServiceImpl; + + +static const IServiceProviderVtbl IServiceProviderImpl_Vtbl; +static const IProfferServiceVtbl IProfferServiceImpl_Vtbl; + +IServiceProvider* IServiceProviderImpl_Construct(void) +{ + IServiceProviderImpl *obj; + + obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); + obj->lpVtbl = &IServiceProviderImpl_Vtbl; + obj->ref = 1; + + return (IServiceProvider*)obj; +} + +IProfferService* IProfferServiceImpl_Construct(void) +{ + IProfferServiceImpl *obj; + + obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); + obj->lpVtbl = &IProfferServiceImpl_Vtbl; + obj->ref = 1; + + return (IProfferService*)obj; +} + +static HRESULT WINAPI IServiceProviderImpl_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObj) +{ + IServiceProviderImpl *This = (IServiceProviderImpl *)iface; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IServiceProvider)) + { + *ppvObj = This; + } + + if(*ppvObj) + { + IUnknown_AddRef(iface); + /* native uses redefined IID_IServiceProvider symbol, so we can't compare pointers */ + if (IsEqualIID(riid, &IID_IServiceProvider)) + add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI IServiceProviderImpl_AddRef(IServiceProvider *iface) +{ + IServiceProviderImpl *This = (IServiceProviderImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI IServiceProviderImpl_Release(IServiceProvider *iface) +{ + IServiceProviderImpl *This = (IServiceProviderImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + return 0; + } + return ref; +} + +static HRESULT WINAPI IServiceProviderImpl_QueryService( + IServiceProvider *iface, REFGUID service, REFIID riid, void **ppv) +{ + /* native uses redefined pointer for IID_IOleCommandTarget, not one from uuid.lib */ + if (IsEqualIID(riid, &IID_IOleCommandTarget)) + { + add_call(&trace_got, 2, iface, service, &IID_IOleCommandTarget, 0, 0); + *ppv = IOleCommandTargetImpl_Construct(); + } + if (IsEqualIID(riid, &IID_IProfferService)) + { + if (IsEqualIID(service, &IID_IProfferService)) + add_call(&trace_got, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0); + *ppv = IProfferServiceImpl_Construct(); + } + return S_OK; +} + +static const IServiceProviderVtbl IServiceProviderImpl_Vtbl = +{ + IServiceProviderImpl_QueryInterface, + IServiceProviderImpl_AddRef, + IServiceProviderImpl_Release, + IServiceProviderImpl_QueryService +}; + +static void test_IUnknown_QueryServiceExec(void) +{ + IServiceProvider *provider = IServiceProviderImpl_Construct(); + static const GUID dummy_serviceid = { 0xdeadbeef }; + static const GUID dummy_groupid = { 0xbeefbeef }; + call_trace_t trace_expected; + HRESULT hr; + + /* on <=W2K platforms same ordinal used for another export with different + prototype, so skipping using this indirect condition */ + if (is_win2k_and_lower) + { + win_skip("IUnknown_QueryServiceExec is not available\n"); + return; + } + + /* null source pointer */ + hr = pIUnknown_QueryServiceExec(NULL, &dummy_serviceid, &dummy_groupid, 0, 0, 0, 0); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + + /* expected trace: + IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4); + -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &prov ); + -> IServiceProvider_QueryService( prov, serviceid, &IID_IOleCommandTarget, &obj ); + -> IOleCommandTarget_Exec( obj, groupid, arg1, arg2, arg3, arg4 ); + */ + init_call_trace(&trace_expected); + + add_call(&trace_expected, 1, provider, &IID_IServiceProvider, 0, 0, 0); + add_call(&trace_expected, 2, provider, &dummy_serviceid, &IID_IOleCommandTarget, 0, 0); + add_call(&trace_expected, 3, &dummy_groupid, (void*)0x1, (void*)0x2, (void*)0x3, (void*)0x4); + + init_call_trace(&trace_got); + hr = pIUnknown_QueryServiceExec((IUnknown*)provider, &dummy_serviceid, &dummy_groupid, 0x1, 0x2, (void*)0x3, (void*)0x4); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ok_trace(&trace_expected, &trace_got); + + free_call_trace(&trace_expected); + free_call_trace(&trace_got); + + IServiceProvider_Release(provider); +} + + +static HRESULT WINAPI IProfferServiceImpl_QueryInterface(IProfferService *iface, REFIID riid, void **ppvObj) +{ + IProfferServiceImpl *This = (IProfferServiceImpl *)iface; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IProfferService)) + { + *ppvObj = This; + } + else if (IsEqualIID(riid, &IID_IServiceProvider)) + { + *ppvObj = IServiceProviderImpl_Construct(); + add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0); + return S_OK; + } + + if(*ppvObj) + { + IUnknown_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI IProfferServiceImpl_AddRef(IProfferService *iface) +{ + IProfferServiceImpl *This = (IProfferServiceImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI IProfferServiceImpl_Release(IProfferService *iface) +{ + IProfferServiceImpl *This = (IProfferServiceImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + return 0; + } + return ref; +} + +static HRESULT WINAPI IProfferServiceImpl_ProfferService(IProfferService *iface, + REFGUID service, IServiceProvider *pService, DWORD *pCookie) +{ + add_call(&trace_got, 3, service, pService, pCookie, 0, 0); + return S_OK; +} + +static HRESULT WINAPI IProfferServiceImpl_RevokeService(IProfferService *iface, DWORD cookie) +{ + add_call(&trace_got, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0); + return S_OK; +} + +static const IProfferServiceVtbl IProfferServiceImpl_Vtbl = +{ + IProfferServiceImpl_QueryInterface, + IProfferServiceImpl_AddRef, + IProfferServiceImpl_Release, + IProfferServiceImpl_ProfferService, + IProfferServiceImpl_RevokeService +}; + +static void test_IUnknown_ProfferService(void) +{ + IServiceProvider *provider = IServiceProviderImpl_Construct(); + IProfferService *proff = IProfferServiceImpl_Construct(); + static const GUID dummy_serviceid = { 0xdeadbeef }; + call_trace_t trace_expected; + HRESULT hr; + DWORD cookie; + + /* on <=W2K platforms same ordinal used for another export with different + prototype, so skipping using this indirect condition */ + if (is_win2k_and_lower) + { + win_skip("IUnknown_ProfferService is not available\n"); + return; + } + + /* null source pointer */ + hr = pIUnknown_ProfferService(NULL, &dummy_serviceid, 0, 0); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + + /* expected trace: + IUnknown_ProfferService( ptr1, serviceid, arg1, arg2); + -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &provider ); + -> IServiceProvider_QueryService( provider, &IID_IProfferService, &IID_IProfferService, &proffer ); + + if (service pointer not null): + -> IProfferService_ProfferService( proffer, serviceid, arg1, arg2 ); + else + -> IProfferService_RevokeService( proffer, *arg2 ); + */ + init_call_trace(&trace_expected); + + add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0); + add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0); + add_call(&trace_expected, 3, &dummy_serviceid, provider, &cookie, 0, 0); + + init_call_trace(&trace_got); + hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, provider, &cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ok_trace(&trace_expected, &trace_got); + free_call_trace(&trace_got); + free_call_trace(&trace_expected); + + /* same with ::Revoke path */ + init_call_trace(&trace_expected); + + add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0); + add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0); + add_call(&trace_expected, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0); + + init_call_trace(&trace_got); + hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, 0, &cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_trace(&trace_expected, &trace_got); + free_call_trace(&trace_got); + free_call_trace(&trace_expected); + + IServiceProvider_Release(provider); + IProfferService_Release(proff); +} + +static void test_SHCreateWorkerWindowA(void) +{ + WNDCLASSA cliA; + char classA[20]; + HWND hwnd; + LONG_PTR ret; + BOOL res; + + if (is_win2k_and_lower) + { + win_skip("SHCreateWorkerWindowA not available\n"); + return; + } + + hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0); + ok(hwnd != 0, "expected window\n"); + + GetClassName(hwnd, classA, 20); + ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA); + + ret = GetWindowLongPtrA(hwnd, 0); + ok(ret == 0, "got %ld\n", ret); + + /* class info */ + memset(&cliA, 0, sizeof(cliA)); + res = GetClassInfoA(GetModuleHandle("shlwapi.dll"), "WorkerA", &cliA); + ok(res, "failed to get class info\n"); + ok(cliA.style == 0, "got 0x%08x\n", cliA.style); + ok(cliA.cbClsExtra == 0, "got %d\n", cliA.cbClsExtra); + ok(cliA.cbWndExtra == sizeof(LONG_PTR), "got %d\n", cliA.cbWndExtra); + ok(cliA.lpszMenuName == 0, "got %s\n", cliA.lpszMenuName); + + DestroyWindow(hwnd); + + /* set extra bytes */ + hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0xdeadbeef); + ok(hwnd != 0, "expected window\n"); + + GetClassName(hwnd, classA, 20); + ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA); + + ret = GetWindowLongPtrA(hwnd, 0); + ok(ret == 0xdeadbeef, "got %ld\n", ret); + + /* test exstyle */ + ret = GetWindowLongA(hwnd, GWL_EXSTYLE); + ok(ret == WS_EX_WINDOWEDGE, "0x%08lx\n", ret); + + DestroyWindow(hwnd); + + hwnd = pSHCreateWorkerWindowA(0, NULL, WS_EX_TOOLWINDOW, 0, 0, 0); + ret = GetWindowLongA(hwnd, GWL_EXSTYLE); + ok(ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW), "0x%08lx\n", ret); + DestroyWindow(hwnd); +} + +static void init_pointers(void) +{ +#define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord))) + MAKEFUNC(SHAllocShared, 7); + MAKEFUNC(SHLockShared, 8); + MAKEFUNC(SHUnlockShared, 9); + MAKEFUNC(SHFreeShared, 10); + MAKEFUNC(GetAcceptLanguagesA, 14); + MAKEFUNC(SHSetWindowBits, 165); + MAKEFUNC(ConnectToConnectionPoint, 168); + MAKEFUNC(SHSearchMapInt, 198); + MAKEFUNC(SHCreateWorkerWindowA, 257); + MAKEFUNC(GUIDFromStringA, 269); + MAKEFUNC(SHPackDispParams, 282); + MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283); + MAKEFUNC(IConnectionPoint_SimpleInvoke, 284); + MAKEFUNC(SHFormatDateTimeA, 353); + MAKEFUNC(SHFormatDateTimeW, 354); + MAKEFUNC(SHGetObjectCompatFlags, 476); + MAKEFUNC(IUnknown_QueryServiceExec, 484); + MAKEFUNC(SHPropertyBag_ReadLONG, 496); + MAKEFUNC(IUnknown_ProfferService, 514); +#undef MAKEFUNC +} + START_TEST(ordinal) { - hShlwapi = GetModuleHandleA("shlwapi.dll"); - - pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14); - pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198); - pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7); - pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8); - pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9); - pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10); - pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282); - pIConnectionPoint_SimpleInvoke=(void*)GetProcAddress(hShlwapi,(char*)284); - pIConnectionPoint_InvokeWithCancel=(void*)GetProcAddress(hShlwapi,(char*)283); - pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168); - pSHPropertyBag_ReadLONG=(void*)GetProcAddress(hShlwapi,(char*)496); - - hmlang = LoadLibraryA("mlang.dll"); - pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A"); - - test_GetAcceptLanguagesA(); - test_SHSearchMapInt(); - test_alloc_shared(); - test_fdsa(); - test_GetShellSecurityDescriptor(); - test_SHPackDispParams(); - test_IConnectionPoint(); - test_SHPropertyBag_ReadLONG(); + hShlwapi = GetModuleHandleA("shlwapi.dll"); + is_win2k_and_lower = GetProcAddress(hShlwapi, "StrChrNW") == 0; + + init_pointers(); + + hmlang = LoadLibraryA("mlang.dll"); + pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A"); + + test_GetAcceptLanguagesA(); + test_SHSearchMapInt(); + test_alloc_shared(); + test_fdsa(); + test_GetShellSecurityDescriptor(); + test_SHPackDispParams(); + test_IConnectionPoint(); + test_SHPropertyBag_ReadLONG(); + test_SHSetWindowBits(); + test_SHFormatDateTimeA(); + test_SHFormatDateTimeW(); + test_SHGetObjectCompatFlags(); + test_IUnknown_QueryServiceExec(); + test_IUnknown_ProfferService(); + test_SHCreateWorkerWindowA(); } diff --git a/rostests/winetests/shlwapi/path.c b/rostests/winetests/shlwapi/path.c index e52502fdf58..3e83a4556c6 100755 --- a/rostests/winetests/shlwapi/path.c +++ b/rostests/winetests/shlwapi/path.c @@ -28,12 +28,12 @@ #include "shlwapi.h" #include "wininet.h" -static HMODULE hShlwapi; static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD); static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD); static LPWSTR (WINAPI *pPathCombineW)(LPWSTR, LPCWSTR, LPCWSTR); static HRESULT (WINAPI *pPathCreateFromUrlA)(LPCSTR, LPSTR, LPDWORD, DWORD); static HRESULT (WINAPI *pPathCreateFromUrlW)(LPCWSTR, LPWSTR, LPDWORD, DWORD); +static BOOL (WINAPI *pPathAppendA)(LPSTR, LPCSTR); /* ################ */ @@ -300,6 +300,15 @@ static void test_PathIsValidCharA(void) BOOL ret; unsigned int c; + /* For whatever reason, PathIsValidCharA and PathAppendA share the same + * ordinal number in some native versions. Check this to prevent a crash. + */ + if (!pPathIsValidCharA || pPathIsValidCharA == (void*)pPathAppendA) + { + win_skip("PathIsValidCharA isn't available\n"); + return; + } + for (c = 0; c < 0x7f; c++) { ret = pPathIsValidCharA( c, ~0U ); @@ -318,6 +327,12 @@ static void test_PathIsValidCharW(void) BOOL ret; unsigned int c; + if (!pPathIsValidCharW) + { + win_skip("PathIsValidCharW isn't available\n"); + return; + } + for (c = 0; c < 0x7f; c++) { ret = pPathIsValidCharW( c, ~0U ); @@ -392,7 +407,13 @@ static void test_PathCombineW(void) WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH]; static const WCHAR expout[] = {'C',':','\\','A','A',0}; int i; - + + if (!pPathCombineW) + { + win_skip("PathCombineW isn't available\n"); + return; + } + wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); /* NULL test */ @@ -1312,43 +1333,60 @@ static void test_PathUnquoteSpaces(void) } } +static void test_PathGetDriveNumber(void) +{ + static const CHAR test1A[] = "a:\\test.file"; + static const CHAR test2A[] = "file:////b:\\test.file"; + static const CHAR test3A[] = "file:///c:\\test.file"; + static const CHAR test4A[] = "file:\\\\c:\\test.file"; + int ret; + + SetLastError(0xdeadbeef); + ret = PathGetDriveNumberA(NULL); + ok(ret == -1, "got %d\n", ret); + ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError()); + + ret = PathGetDriveNumberA(test1A); + ok(ret == 0, "got %d\n", ret); + ret = PathGetDriveNumberA(test2A); + ok(ret == -1, "got %d\n", ret); + ret = PathGetDriveNumberA(test3A); + ok(ret == -1, "got %d\n", ret); + ret = PathGetDriveNumberA(test4A); + ok(ret == -1, "got %d\n", ret); +} + /* ################ */ START_TEST(path) { - hShlwapi = GetModuleHandleA("shlwapi.dll"); - pPathCreateFromUrlA = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlA"); - pPathCreateFromUrlW = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlW"); - - test_PathSearchAndQualify(); - test_PathCreateFromUrl(); - test_PathIsUrl(); - - test_PathAddBackslash(); - test_PathMakePretty(); - test_PathMatchSpec(); - - /* For whatever reason, PathIsValidCharA and PathAppendA share the same - * ordinal number in some native versions. Check this to prevent a crash. - */ - pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455); - if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA")) - { - test_PathIsValidCharA(); + HMODULE hShlwapi = GetModuleHandleA("shlwapi.dll"); - pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456); - if (pPathIsValidCharW) test_PathIsValidCharW(); - } + pPathCreateFromUrlA = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlA"); + pPathCreateFromUrlW = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlW"); + pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW"); + pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455); + pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456); + pPathAppendA = (void*)GetProcAddress(hShlwapi, "PathAppendA"); - pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW"); - if (pPathCombineW) - test_PathCombineW(); + test_PathSearchAndQualify(); + test_PathCreateFromUrl(); + test_PathIsUrl(); + + test_PathAddBackslash(); + test_PathMakePretty(); + test_PathMatchSpec(); - test_PathCombineA(); - test_PathAppendA(); - test_PathCanonicalizeA(); - test_PathFindExtensionA(); - test_PathBuildRootA(); - test_PathCommonPrefixA(); - test_PathUnquoteSpaces(); + test_PathIsValidCharA(); + test_PathIsValidCharW(); + + test_PathCombineW(); + test_PathCombineA(); + test_PathAppendA(); + test_PathCanonicalizeA(); + test_PathFindExtensionA(); + test_PathBuildRootA(); + test_PathCommonPrefixA(); + test_PathUnquoteSpaces(); + test_PathGetDriveNumber(); } diff --git a/rostests/winetests/shlwapi/shlwapi.rbuild b/rostests/winetests/shlwapi/shlwapi.rbuild index cd5cffd19a3..0fe700994c5 100644 --- a/rostests/winetests/shlwapi/shlwapi.rbuild +++ b/rostests/winetests/shlwapi/shlwapi.rbuild @@ -3,7 +3,7 @@ . - + assoc.c clist.c clsid.c @@ -21,6 +21,7 @@ advapi32 ole32 oleaut32 + user32 ntdll diff --git a/rostests/winetests/shlwapi/string.c b/rostests/winetests/shlwapi/string.c index 00f0b023046..17c652de411 100755 --- a/rostests/winetests/shlwapi/string.c +++ b/rostests/winetests/shlwapi/string.c @@ -863,6 +863,33 @@ static void test_StrXXX_overflows(void) else win_skip("StrCatBuffA() is not available\n"); +if (0) +{ + /* crashes on XP */ + StrCpyNW(wbuf, (LPCWSTR)0x1, 10); + StrCpyNW((LPWSTR)0x1, wstr1, 10); +} + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, (LPCWSTR)0x1, 1), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], 0, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, 0, 10), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], 0, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, 0, 0), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, wstr1, 0), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + memset(wbuf, 0xbf, sizeof(wbuf)); expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p"); expect_eq(wbuf[9], 0, WCHAR, "%x"); diff --git a/rostests/winetests/shlwapi/url.c b/rostests/winetests/shlwapi/url.c index 3d86ae7c5e1..0dd96431811 100644 --- a/rostests/winetests/shlwapi/url.c +++ b/rostests/winetests/shlwapi/url.c @@ -160,6 +160,7 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = { {"A", 0, S_OK, "A", FALSE}, {"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/, S_OK, "/uri-res/N2R?urn:sha1:B3K", FALSE} /*LimeWire online installer calls this*/, {"http:www.winehq.org/dir/../index.html", 0, S_OK, "http:www.winehq.org/index.html"}, + {"http://localhost/test.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/test.html"} }; /* ################ */ @@ -278,6 +279,11 @@ static const TEST_URL_COMBINE TEST_COMBINE[] = { {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."}, {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"}, {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}, + {"file:///C:\\dir\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir/file.txt#hash/test.txt"}, + {"file:///C:\\dir\\file.html#hash\\hash", "test.html", 0, S_OK, "file:///C:/dir/test.html"}, + {"file:///C:\\dir\\file.htm#hash\\hash", "test.htm", 0, S_OK, "file:///C:/dir/test.htm"}, + {"file:///C:\\dir\\file.hTmL#hash\\hash", "test.hTmL", 0, S_OK, "file:///C:/dir/test.hTmL"}, + {"file:///C:\\dir.html\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir.html/file.txt#hash/test.txt"}, {"C:\\winehq\\winehq.txt", "C:\\Test\\test.txt", 0, S_OK, "file:///C:/Test/test.txt"}, {"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK, "http://www.winehq.org/test/test%20file.txt"}, {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/test/test%20file.txt"}, @@ -537,6 +543,13 @@ static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const HRESULT res; DWORD dwSize; + dwSize = 1; + res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags); + ok(res == E_POINTER, "UrlGetPart for \"%s\" gave: 0x%08x\n", szUrl, res); + ok(dwSize == strlen(szExpected)+1 || + (*szExpected == '?' && dwSize == strlen(szExpected)), + "UrlGetPart for \"%s\" gave size: %u\n", szUrl, dwSize); + dwSize = INTERNET_MAX_URL_LENGTH; res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags); ok(res == S_OK, @@ -570,6 +583,7 @@ static void test_UrlGetPart(void) { const char* file_url = "file://h o s t/c:/windows/file"; const char* http_url = "http://user:pass 123@www.wine hq.org"; + const char* res_url = "res://some.dll/find.dlg"; const char* about_url = "about:blank"; CHAR szPart[INTERNET_MAX_URL_LENGTH]; @@ -581,20 +595,38 @@ static void test_UrlGetPart(void) return; } + res = pUrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0); + ok(res == E_INVALIDARG, "null params gave: 0x%08x\n", res); + + res = pUrlGetPartA(NULL, szPart, &dwSize, URL_PART_SCHEME, 0); + ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res); + + res = pUrlGetPartA(res_url, NULL, &dwSize, URL_PART_SCHEME, 0); + ok(res == E_INVALIDARG, "null szPart gave: 0x%08x\n", res); + + res = pUrlGetPartA(res_url, szPart, NULL, URL_PART_SCHEME, 0); + ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res); + + dwSize = 0; + szPart[0]='x'; szPart[1]=0; + res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0); + ok(res == E_INVALIDARG, "UrlGetPartA(*pcchOut = 0) returned %08X\n", res); + ok(szPart[0] == 'x' && szPart[1] == 0, "UrlGetPartA(*pcchOut = 0) modified szPart: \"%s\"\n", szPart); + ok(dwSize == 0, "dwSize = %d\n", dwSize); + dwSize = sizeof szPart; szPart[0]='x'; szPart[1]=0; res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0); - todo_wine { ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); - } + ok(dwSize == 0, "dwSize = %d\n", dwSize); + dwSize = sizeof szPart; szPart[0]='x'; szPart[1]=0; res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0); - todo_wine { ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); - } + ok(dwSize == 0, "dwSize = %d\n", dwSize); test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost"); test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21"); @@ -614,9 +646,20 @@ static void test_UrlGetPart(void) res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0); ok(res==E_FAIL, "returned %08x\n", res); + test_url_part(res_url, URL_PART_SCHEME, 0, "res"); + test_url_part("http://www.winehq.org", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, "http:www.winehq.org"); + + dwSize = sizeof szPart; + szPart[0]='x'; szPart[1]=0; + res = pUrlGetPartA(res_url, szPart, &dwSize, URL_PART_QUERY, 0); + ok(res==S_FALSE, "UrlGetPartA returned %08X\n", res); + ok(szPart[0]==0, "UrlGetPartA gave \"%s\" instead of \"\"\n", szPart); + ok(dwSize == 0, "dwSize = %d\n", dwSize); + dwSize = sizeof(szPart); res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0); ok(res==S_FALSE, "returned %08x\n", res); + ok(dwSize == 0, "dwSize = %d\n", dwSize); dwSize = sizeof(szPart); szPart[0] = 'x'; szPart[1] = '\0'; @@ -624,6 +667,11 @@ static void test_UrlGetPart(void) ok(res==S_FALSE, "returned %08x\n", res); ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]); ok(dwSize == 0, "dwSize = %d\n", dwSize); + + dwSize = sizeof(szPart); + szPart[0] = 'x'; szPart[1] = '\0'; + res = pUrlGetPartA("index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0); + ok(res==E_FAIL, "returned %08x\n", res); } /* ########################### */ @@ -1000,6 +1048,15 @@ static void test_UrlCreateFromPath(void) /* ########################### */ +static void test_UrlIs_null(DWORD flag) +{ + BOOL ret; + ret = pUrlIsA(NULL, flag); + ok(ret == FALSE, "pUrlIsA(NULL, %d) failed\n", flag); + ret = pUrlIsW(NULL, flag); + ok(ret == FALSE, "pUrlIsW(NULL, %d) failed\n", flag); +} + static void test_UrlIs(void) { BOOL ret; @@ -1011,6 +1068,14 @@ static void test_UrlIs(void) return; } + test_UrlIs_null(URLIS_APPLIABLE); + test_UrlIs_null(URLIS_DIRECTORY); + test_UrlIs_null(URLIS_FILEURL); + test_UrlIs_null(URLIS_HASQUERY); + test_UrlIs_null(URLIS_NOHISTORY); + test_UrlIs_null(URLIS_OPAQUE); + test_UrlIs_null(URLIS_URL); + for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) { MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80); diff --git a/rostests/winetests/urlmon/generated.c b/rostests/winetests/urlmon/generated.c index 8a2f353b043..63e892bc543 100644 --- a/rostests/winetests/urlmon/generated.c +++ b/rostests/winetests/urlmon/generated.c @@ -54,45 +54,289 @@ * Test helper macros */ -#ifdef _WIN64 +#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); -# define TEST_TYPE_SIZE(type, size) +#ifdef TYPE_ALIGNMENT +# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); +#else # define TEST_TYPE_ALIGN(type, align) +#endif + +#ifdef _TYPE_ALIGNMENT +# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); +# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); +#else # define TEST_TARGET_ALIGN(type, align) # define TEST_FIELD_ALIGN(type, field, align) -# define TEST_FIELD_OFFSET(type, field, offset) +#endif -#else +#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); -# define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); +#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) +#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) +#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); +#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); -# ifdef TYPE_ALIGNMENT -# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); -# else -# define TEST_TYPE_ALIGN(type, align) -# endif -# ifdef _TYPE_ALIGNMENT -# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); -# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); -# else -# define TEST_TARGET_ALIGN(type, align) -# define TEST_FIELD_ALIGN(type, field, align) -# endif +#ifdef _WIN64 -# define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); +static void test_pack_BINDINFO(void) +{ + /* BINDINFO */ + TEST_FIELD_SIZE (BINDINFO, cbSize, 4) + TEST_FIELD_ALIGN (BINDINFO, cbSize, 4) + TEST_FIELD_OFFSET(BINDINFO, cbSize, 0) + TEST_FIELD_SIZE (BINDINFO, szExtraInfo, 8) + TEST_FIELD_ALIGN (BINDINFO, szExtraInfo, 8) + TEST_FIELD_OFFSET(BINDINFO, szExtraInfo, 8) +} -#endif +static void test_pack_IBindHost(void) +{ + /* IBindHost */ +} -#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) -#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) -#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); -#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); +static void test_pack_IBindHostVtbl(void) +{ + /* IBindHostVtbl */ +} + +static void test_pack_IBindStatusCallback(void) +{ + /* IBindStatusCallback */ +} +static void test_pack_IBindStatusCallbackVtbl(void) +{ + /* IBindStatusCallbackVtbl */ +} + +static void test_pack_IBinding(void) +{ + /* IBinding */ +} + +static void test_pack_IBindingVtbl(void) +{ + /* IBindingVtbl */ +} + +static void test_pack_IInternetProtocolInfo(void) +{ + /* IInternetProtocolInfo */ +} + +static void test_pack_IInternetProtocolInfoVtbl(void) +{ + /* IInternetProtocolInfoVtbl */ +} + +static void test_pack_IInternetSession(void) +{ + /* IInternetSession */ +} + +static void test_pack_IInternetSessionVtbl(void) +{ + /* IInternetSessionVtbl */ +} + +static void test_pack_IPersistMoniker(void) +{ + /* IPersistMoniker */ +} + +static void test_pack_IPersistMonikerVtbl(void) +{ + /* IPersistMonikerVtbl */ +} + +static void test_pack_IWinInetHttpInfo(void) +{ + /* IWinInetHttpInfo */ +} + +static void test_pack_IWinInetHttpInfoVtbl(void) +{ + /* IWinInetHttpInfoVtbl */ +} + +static void test_pack_IWinInetInfo(void) +{ + /* IWinInetInfo */ +} + +static void test_pack_IWinInetInfoVtbl(void) +{ + /* IWinInetInfoVtbl */ +} + +static void test_pack_LPBINDHOST(void) +{ + /* LPBINDHOST */ + TEST_TYPE_SIZE (LPBINDHOST, 8) + TEST_TYPE_ALIGN (LPBINDHOST, 8) +} + +static void test_pack_LPBINDING(void) +{ + /* LPBINDING */ + TEST_TYPE_SIZE (LPBINDING, 8) + TEST_TYPE_ALIGN (LPBINDING, 8) +} + +static void test_pack_LPBINDSTATUSCALLBACK(void) +{ + /* LPBINDSTATUSCALLBACK */ + TEST_TYPE_SIZE (LPBINDSTATUSCALLBACK, 8) + TEST_TYPE_ALIGN (LPBINDSTATUSCALLBACK, 8) +} + +static void test_pack_LPIINTERNETPROTOCOLINFO(void) +{ + /* LPIINTERNETPROTOCOLINFO */ + TEST_TYPE_SIZE (LPIINTERNETPROTOCOLINFO, 8) + TEST_TYPE_ALIGN (LPIINTERNETPROTOCOLINFO, 8) +} + +static void test_pack_LPIINTERNETSESSION(void) +{ + /* LPIINTERNETSESSION */ + TEST_TYPE_SIZE (LPIINTERNETSESSION, 8) + TEST_TYPE_ALIGN (LPIINTERNETSESSION, 8) +} + +static void test_pack_LPPERSISTMONIKER(void) +{ + /* LPPERSISTMONIKER */ + TEST_TYPE_SIZE (LPPERSISTMONIKER, 8) + TEST_TYPE_ALIGN (LPPERSISTMONIKER, 8) +} + +static void test_pack_LPREMFORMATETC(void) +{ + /* LPREMFORMATETC */ + TEST_TYPE_SIZE (LPREMFORMATETC, 8) + TEST_TYPE_ALIGN (LPREMFORMATETC, 8) +} + +static void test_pack_LPREMSECURITY_ATTRIBUTES(void) +{ + /* LPREMSECURITY_ATTRIBUTES */ + TEST_TYPE_SIZE (LPREMSECURITY_ATTRIBUTES, 8) + TEST_TYPE_ALIGN (LPREMSECURITY_ATTRIBUTES, 8) +} + +static void test_pack_LPWININETHTTPINFO(void) +{ + /* LPWININETHTTPINFO */ + TEST_TYPE_SIZE (LPWININETHTTPINFO, 8) + TEST_TYPE_ALIGN (LPWININETHTTPINFO, 8) +} + +static void test_pack_LPWININETINFO(void) +{ + /* LPWININETINFO */ + TEST_TYPE_SIZE (LPWININETINFO, 8) + TEST_TYPE_ALIGN (LPWININETINFO, 8) +} + +static void test_pack_PREMSECURITY_ATTRIBUTES(void) +{ + /* PREMSECURITY_ATTRIBUTES */ + TEST_TYPE_SIZE (PREMSECURITY_ATTRIBUTES, 8) + TEST_TYPE_ALIGN (PREMSECURITY_ATTRIBUTES, 8) +} + +static void test_pack_REMSECURITY_ATTRIBUTES(void) +{ + /* REMSECURITY_ATTRIBUTES */ + TEST_TYPE_SIZE (REMSECURITY_ATTRIBUTES, 12) + TEST_TYPE_ALIGN (REMSECURITY_ATTRIBUTES, 4) + TEST_FIELD_SIZE (REMSECURITY_ATTRIBUTES, nLength, 4) + TEST_FIELD_ALIGN (REMSECURITY_ATTRIBUTES, nLength, 4) + TEST_FIELD_OFFSET(REMSECURITY_ATTRIBUTES, nLength, 0) + TEST_FIELD_SIZE (REMSECURITY_ATTRIBUTES, lpSecurityDescriptor, 4) + TEST_FIELD_ALIGN (REMSECURITY_ATTRIBUTES, lpSecurityDescriptor, 4) + TEST_FIELD_OFFSET(REMSECURITY_ATTRIBUTES, lpSecurityDescriptor, 4) + TEST_FIELD_SIZE (REMSECURITY_ATTRIBUTES, bInheritHandle, 4) + TEST_FIELD_ALIGN (REMSECURITY_ATTRIBUTES, bInheritHandle, 4) + TEST_FIELD_OFFSET(REMSECURITY_ATTRIBUTES, bInheritHandle, 8) +} + +static void test_pack_RemBINDINFO(void) +{ + /* RemBINDINFO */ + TEST_TYPE_SIZE (RemBINDINFO, 96) + TEST_TYPE_ALIGN (RemBINDINFO, 8) + TEST_FIELD_SIZE (RemBINDINFO, cbSize, 4) + TEST_FIELD_ALIGN (RemBINDINFO, cbSize, 4) + TEST_FIELD_OFFSET(RemBINDINFO, cbSize, 0) + TEST_FIELD_SIZE (RemBINDINFO, szExtraInfo, 8) + TEST_FIELD_ALIGN (RemBINDINFO, szExtraInfo, 8) + TEST_FIELD_OFFSET(RemBINDINFO, szExtraInfo, 8) + TEST_FIELD_SIZE (RemBINDINFO, grfBindInfoF, 4) + TEST_FIELD_ALIGN (RemBINDINFO, grfBindInfoF, 4) + TEST_FIELD_OFFSET(RemBINDINFO, grfBindInfoF, 16) + TEST_FIELD_SIZE (RemBINDINFO, dwBindVerb, 4) + TEST_FIELD_ALIGN (RemBINDINFO, dwBindVerb, 4) + TEST_FIELD_OFFSET(RemBINDINFO, dwBindVerb, 20) + TEST_FIELD_SIZE (RemBINDINFO, szCustomVerb, 8) + TEST_FIELD_ALIGN (RemBINDINFO, szCustomVerb, 8) + TEST_FIELD_OFFSET(RemBINDINFO, szCustomVerb, 24) + TEST_FIELD_SIZE (RemBINDINFO, cbstgmedData, 4) + TEST_FIELD_ALIGN (RemBINDINFO, cbstgmedData, 4) + TEST_FIELD_OFFSET(RemBINDINFO, cbstgmedData, 32) + TEST_FIELD_SIZE (RemBINDINFO, dwOptions, 4) + TEST_FIELD_ALIGN (RemBINDINFO, dwOptions, 4) + TEST_FIELD_OFFSET(RemBINDINFO, dwOptions, 36) + TEST_FIELD_SIZE (RemBINDINFO, dwOptionsFlags, 4) + TEST_FIELD_ALIGN (RemBINDINFO, dwOptionsFlags, 4) + TEST_FIELD_OFFSET(RemBINDINFO, dwOptionsFlags, 40) + TEST_FIELD_SIZE (RemBINDINFO, dwCodePage, 4) + TEST_FIELD_ALIGN (RemBINDINFO, dwCodePage, 4) + TEST_FIELD_OFFSET(RemBINDINFO, dwCodePage, 44) + TEST_FIELD_SIZE (RemBINDINFO, securityAttributes, 12) + TEST_FIELD_ALIGN (RemBINDINFO, securityAttributes, 4) + TEST_FIELD_OFFSET(RemBINDINFO, securityAttributes, 48) + TEST_FIELD_SIZE (RemBINDINFO, iid, 16) + TEST_FIELD_ALIGN (RemBINDINFO, iid, 4) + TEST_FIELD_OFFSET(RemBINDINFO, iid, 60) + TEST_FIELD_SIZE (RemBINDINFO, pUnk, 8) + TEST_FIELD_ALIGN (RemBINDINFO, pUnk, 8) + TEST_FIELD_OFFSET(RemBINDINFO, pUnk, 80) + TEST_FIELD_SIZE (RemBINDINFO, dwReserved, 4) + TEST_FIELD_ALIGN (RemBINDINFO, dwReserved, 4) + TEST_FIELD_OFFSET(RemBINDINFO, dwReserved, 88) +} + +static void test_pack_RemFORMATETC(void) +{ + /* RemFORMATETC */ + TEST_TYPE_SIZE (RemFORMATETC, 20) + TEST_TYPE_ALIGN (RemFORMATETC, 4) + TEST_FIELD_SIZE (RemFORMATETC, cfFormat, 4) + TEST_FIELD_ALIGN (RemFORMATETC, cfFormat, 4) + TEST_FIELD_OFFSET(RemFORMATETC, cfFormat, 0) + TEST_FIELD_SIZE (RemFORMATETC, ptd, 4) + TEST_FIELD_ALIGN (RemFORMATETC, ptd, 4) + TEST_FIELD_OFFSET(RemFORMATETC, ptd, 4) + TEST_FIELD_SIZE (RemFORMATETC, dwAspect, 4) + TEST_FIELD_ALIGN (RemFORMATETC, dwAspect, 4) + TEST_FIELD_OFFSET(RemFORMATETC, dwAspect, 8) + TEST_FIELD_SIZE (RemFORMATETC, lindex, 4) + TEST_FIELD_ALIGN (RemFORMATETC, lindex, 4) + TEST_FIELD_OFFSET(RemFORMATETC, lindex, 12) + TEST_FIELD_SIZE (RemFORMATETC, tymed, 4) + TEST_FIELD_ALIGN (RemFORMATETC, tymed, 4) + TEST_FIELD_OFFSET(RemFORMATETC, tymed, 16) +} + +#else /* _WIN64 */ static void test_pack_BINDINFO(void) { - /* BINDINFO (pack 4) */ + /* BINDINFO */ TEST_FIELD_SIZE (BINDINFO, cbSize, 4) TEST_FIELD_ALIGN (BINDINFO, cbSize, 4) TEST_FIELD_OFFSET(BINDINFO, cbSize, 0) @@ -108,7 +352,7 @@ static void test_pack_IBindHost(void) static void test_pack_IBindHostVtbl(void) { - /* IBindHostVtbl (pack 4) */ + /* IBindHostVtbl */ } static void test_pack_IBindStatusCallback(void) @@ -118,7 +362,7 @@ static void test_pack_IBindStatusCallback(void) static void test_pack_IBindStatusCallbackVtbl(void) { - /* IBindStatusCallbackVtbl (pack 4) */ + /* IBindStatusCallbackVtbl */ } static void test_pack_IBinding(void) @@ -128,7 +372,7 @@ static void test_pack_IBinding(void) static void test_pack_IBindingVtbl(void) { - /* IBindingVtbl (pack 4) */ + /* IBindingVtbl */ } static void test_pack_IInternetProtocolInfo(void) @@ -138,7 +382,7 @@ static void test_pack_IInternetProtocolInfo(void) static void test_pack_IInternetProtocolInfoVtbl(void) { - /* IInternetProtocolInfoVtbl (pack 4) */ + /* IInternetProtocolInfoVtbl */ } static void test_pack_IInternetSession(void) @@ -148,7 +392,7 @@ static void test_pack_IInternetSession(void) static void test_pack_IInternetSessionVtbl(void) { - /* IInternetSessionVtbl (pack 4) */ + /* IInternetSessionVtbl */ } static void test_pack_IPersistMoniker(void) @@ -158,7 +402,7 @@ static void test_pack_IPersistMoniker(void) static void test_pack_IPersistMonikerVtbl(void) { - /* IPersistMonikerVtbl (pack 4) */ + /* IPersistMonikerVtbl */ } static void test_pack_IWinInetHttpInfo(void) @@ -168,7 +412,7 @@ static void test_pack_IWinInetHttpInfo(void) static void test_pack_IWinInetHttpInfoVtbl(void) { - /* IWinInetHttpInfoVtbl (pack 4) */ + /* IWinInetHttpInfoVtbl */ } static void test_pack_IWinInetInfo(void) @@ -178,7 +422,7 @@ static void test_pack_IWinInetInfo(void) static void test_pack_IWinInetInfoVtbl(void) { - /* IWinInetInfoVtbl (pack 4) */ + /* IWinInetInfoVtbl */ } static void test_pack_LPBINDHOST(void) @@ -260,7 +504,7 @@ static void test_pack_PREMSECURITY_ATTRIBUTES(void) static void test_pack_REMSECURITY_ATTRIBUTES(void) { - /* REMSECURITY_ATTRIBUTES (pack 4) */ + /* REMSECURITY_ATTRIBUTES */ TEST_TYPE_SIZE (REMSECURITY_ATTRIBUTES, 12) TEST_TYPE_ALIGN (REMSECURITY_ATTRIBUTES, 4) TEST_FIELD_SIZE (REMSECURITY_ATTRIBUTES, nLength, 4) @@ -276,7 +520,7 @@ static void test_pack_REMSECURITY_ATTRIBUTES(void) static void test_pack_RemBINDINFO(void) { - /* RemBINDINFO (pack 4) */ + /* RemBINDINFO */ TEST_TYPE_SIZE (RemBINDINFO, 72) TEST_TYPE_ALIGN (RemBINDINFO, 4) TEST_FIELD_SIZE (RemBINDINFO, cbSize, 4) @@ -322,7 +566,7 @@ static void test_pack_RemBINDINFO(void) static void test_pack_RemFORMATETC(void) { - /* RemFORMATETC (pack 4) */ + /* RemFORMATETC */ TEST_TYPE_SIZE (RemFORMATETC, 20) TEST_TYPE_ALIGN (RemFORMATETC, 4) TEST_FIELD_SIZE (RemFORMATETC, cfFormat, 4) @@ -342,6 +586,8 @@ static void test_pack_RemFORMATETC(void) TEST_FIELD_OFFSET(RemFORMATETC, tymed, 16) } +#endif /* _WIN64 */ + static void test_pack(void) { test_pack_BINDINFO(); @@ -379,9 +625,5 @@ static void test_pack(void) START_TEST(generated) { -#ifdef _WIN64 - ok(0, "The type size / alignment tests don't support Win64 yet\n"); -#else test_pack(); -#endif } diff --git a/rostests/winetests/urlmon/misc.c b/rostests/winetests/urlmon/misc.c index 2e77c1bc237..259c5a0399a 100644 --- a/rostests/winetests/urlmon/misc.c +++ b/rostests/winetests/urlmon/misc.c @@ -63,6 +63,8 @@ DEFINE_EXPECT(QI_IInternetProtocolInfo); DEFINE_EXPECT(CreateInstance); DEFINE_EXPECT(unk_Release); +static HRESULT (WINAPI *pCoInternetCompareUrl)(LPCWSTR, LPCWSTR, DWORD); + static void test_CreateFormatEnum(void) { IEnumFORMATETC *fenum = NULL, *fenum2 = NULL; @@ -363,13 +365,18 @@ static void test_CoInternetCompareUrl(void) { HRESULT hres; - hres = CoInternetCompareUrl(url1, url1, 0); + if (!pCoInternetCompareUrl) { + win_skip("CoInternetCompareUrl not found\n"); + return; + } + + hres = pCoInternetCompareUrl(url1, url1, 0); ok(hres == S_OK, "CoInternetParseUrl failed: %08x\n", hres); - hres = CoInternetCompareUrl(url1, url3, 0); + hres = pCoInternetCompareUrl(url1, url3, 0); ok(hres == S_FALSE, "CoInternetParseUrl failed: %08x\n", hres); - hres = CoInternetCompareUrl(url3, url1, 0); + hres = pCoInternetCompareUrl(url3, url1, 0); ok(hres == S_FALSE, "CoInternetParseUrl failed: %08x\n", hres); } @@ -1402,10 +1409,15 @@ static void test_IsValidURL(void) START_TEST(misc) { + HMODULE hurlmon; + OleInitialize(NULL); register_protocols(); + hurlmon = GetModuleHandle("urlmon.dll"); + pCoInternetCompareUrl = (void *) GetProcAddress(hurlmon, "CoInternetCompareUrl"); + test_CreateFormatEnum(); test_RegisterFormatEnumerator(); test_CoInternetParseUrl(); diff --git a/rostests/winetests/urlmon/sec_mgr.c b/rostests/winetests/urlmon/sec_mgr.c index e4416981dac..239da6c697c 100644 --- a/rostests/winetests/urlmon/sec_mgr.c +++ b/rostests/winetests/urlmon/sec_mgr.c @@ -1,6 +1,6 @@ /* * Copyright 2005-2006 Jacek Caban for CodeWeavers - * Copyright 2009 Detlef Riekenberg + * Copyright 2009-2010 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,21 +35,22 @@ #include "initguid.h" +static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, DWORD); + static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l', '/','b','l','a','n','k','.','h','t','m',0}; static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0}; static const WCHAR url3[] = {'f','i','l','e',':','/','/','c',':','\\','I','n','d','e','x','.','h','t','m',0}; static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e', '%','2','e','j','p','g',0}; -static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q', - '.','o','r','g',0}; +static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t',0}; static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; -static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/', - 'f','i','l','e','.','t','e','s','t',0}; +static const WCHAR url7[] = {'f','t','p',':','/','/','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t','/','f','i','l','e','.','t','e','s','t',0}; static const WCHAR url8[] = {'t','e','s','t',':','1','2','3','a','b','c',0}; -static const WCHAR url9[] = - {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g', - '/','s','i','t','e','/','a','b','o','u','t',0}; +static const WCHAR url9[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t', '/','s','i','t','e','/','a','b','o','u','t',0}; static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e', '.','j','p','g',0}; @@ -58,11 +59,11 @@ static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0}; -static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','w','i','n','e','h','q', - '.','o','r','g',3,0,0,0}; +static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t',3,0,0,0}; static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0}; -static const BYTE secid7[] = {'f','t','p',':','w','i','n','e','h','q','.','o','r','g', - 3,0,0,0}; +static const BYTE secid7[] = {'f','t','p',':','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t',3,0,0,0}; static const BYTE secid10[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0}; static const BYTE secid10_2[] = @@ -632,7 +633,9 @@ static void test_InternetSecurityMarshalling(void) ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres); hres = CoMarshalInterface(stream, &IID_IInternetSecurityManager, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); - ok(hres == S_OK, "CoMarshalInterface returned: %08x\n", hres); + /* Not supported in W98 */ + ok(hres == S_OK || broken(hres == REGDB_E_IIDNOTREG), + "CoMarshalInterface returned: %08x\n", hres); IStream_Release(stream); IUnknown_Release(unk); @@ -641,8 +644,9 @@ static void test_InternetSecurityMarshalling(void) static void test_InternetGetSecurityUrl(void) { - const WCHAR url5_out[] = {'h','t','t','p',':','w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; - const WCHAR url7_out[] = {'f','t','p',':','w','i','n','e','h','q','.','o','r','g',0}; + const WCHAR url5_out[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3', + '.','w','i','n','e','t','e','s','t',0}; + const WCHAR url7_out[] = {'f','t','p',':','z','o','n','e','3','.','w','i','n','e','t','e','s','t',0}; const WCHAR *in[] = {url2, url3, url4, url5, url7, url8, url9, url10}; const WCHAR *out_default[] = {url2, url3, url4, url5_out, url7_out, url8, url5_out, url10}; @@ -652,8 +656,13 @@ static void test_InternetGetSecurityUrl(void) DWORD i; HRESULT hres; + if (!pCoInternetGetSecurityUrl) { + win_skip("CoInternetGetSecurityUrl not found\n"); + return; + } + for(i=0; i #include -static void test_ScriptShape(HDC hdc) +static void test_ScriptItemize( void ) { static const WCHAR test1[] = {'t', 'e', 's', 't',0}; - BOOL ret; + static const WCHAR test2[] = {'1','2','3','-','5','2',0x064a,0x064f,0x0633,0x0627,0x0648,0x0650,0x064a,'7','1','.',0}; + static const WCHAR test3[] = +{0x0e04,0x0e27,0x0e32,0x0e21,0x0e1e,0x0e22,0x0e32,0x0e22,0x0e32, 0x0e21 +,0x0e2d,0x0e22,0x0e39,0x0e48,0x0e17,0x0e35,0x0e48,0x0e44,0x0e2b,0x0e19 +,0x0e04,0x0e27,0x0e32,0x0e21,0x0e2a, 0x0e33,0x0e40,0x0e23,0x0e47,0x0e08, + 0x0e2d,0x0e22,0x0e39,0x0e48,0x0e17,0x0e35,0x0e48,0x0e19,0x0e31,0x0e48,0x0e19,0}; + static const WCHAR test4[] = {'1','2','3','-','5','2',' ','i','s',' ','7','1','.',0}; + static const WCHAR test5[] = +{0x0627,0x0644,0x0635,0x0651,0x0650,0x062d,0x0629,0x064f,' ',0x062a,0x064e, +0x0627,0x062c,0x064c,' ',0x0639,0x064e,0x0644,0x0649,' ', +0x0631,0x064f,0x0624,0x0648,0x0633,0x0650,' ',0x0627,0x0644 +,0x0623,0x0635,0x0650,0x062d,0x0651,0x064e,0x0627,0x0621,0x0650,0}; + SCRIPT_ITEM items[10]; + SCRIPT_CONTROL Control; + SCRIPT_STATE State; + HRESULT hr; + int nItems; + + memset(&Control, 0, sizeof(Control)); + memset(&State, 0, sizeof(State)); + + hr = ScriptItemize(NULL, 4, 10, &Control, &State, items, NULL); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n"); + + hr = ScriptItemize(test1, 4, 10, &Control, &State, NULL, NULL); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n"); + + hr = ScriptItemize(test1, 4, 1, &Control, &State, items, NULL); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2."); + + hr = ScriptItemize(test1, 0, 10, NULL, NULL, items, &nItems); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n"); + + hr = ScriptItemize(test1, 4, 10, NULL, NULL, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 0; + hr = ScriptItemize(test1, 4, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 1; + hr = ScriptItemize(test1, 4, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + todo_wine ok(items[0].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + + hr = ScriptItemize(test2, 16, 10, NULL, NULL, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 6, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 3, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 4, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[2].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[3].iCharPos == 6, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[3].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + ok(items[4].iCharPos == 13, "Wrong CharPos \n"); + ok(items[4].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[4].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[4].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[5].iCharPos == 15, "Wrong CharPos \n"); + ok(items[5].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[5].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[5].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 0; + hr = ScriptItemize(test2, 16, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 4, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + todo_wine ok(items[0].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 6, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 13, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + todo_wine ok(items[2].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + ok(items[3].iCharPos == 15, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[3].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 1; + hr = ScriptItemize(test2, 16, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 4, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + todo_wine ok(items[0].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 6, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 13, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + todo_wine ok(items[2].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + ok(items[3].iCharPos == 15, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[3].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + + hr = ScriptItemize(test3, 41, 10, NULL, NULL, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 0; + hr = ScriptItemize(test3, 41, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 1; + hr = ScriptItemize(test3, 41, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + todo_wine ok(items[0].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + + hr = ScriptItemize(test4, 12, 10, NULL, NULL, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 5, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 3, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 4, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[2].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[3].iCharPos == 7, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[3].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[4].iCharPos == 10, "Wrong CharPos \n"); + ok(items[4].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[4].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[4].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 0; + hr = ScriptItemize(test4, 12, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 5, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 3, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 4, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[2].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[3].iCharPos == 7, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[3].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + ok(items[4].iCharPos == 10, "Wrong CharPos \n"); + ok(items[4].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[4].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[4].a.s.uBidiLevel == 0, "Wrong BidiLevel\n"); + + State.uBidiLevel = 1; + hr = ScriptItemize(test4, 12, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + todo_wine ok(nItems == 4, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 0, "Wrong fRTL\n"); + todo_wine ok(items[0].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + ok(items[1].iCharPos == 6, "Wrong CharPos \n"); + ok(items[1].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[1].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[1].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + ok(items[2].iCharPos == 7, "Wrong CharPos \n"); + ok(items[2].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[2].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + ok(items[2].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + todo_wine ok(items[3].iCharPos == 10, "Wrong CharPos \n"); + ok(items[3].a.fRTL == 0, "Wrong fRTL\n"); + ok(items[3].a.fLayoutRTL == 0, "Wrong fLayoutRTL\n"); + todo_wine ok(items[3].a.s.uBidiLevel == 2, "Wrong BidiLevel\n"); + + hr = ScriptItemize(test5, 38, 10, NULL, NULL, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + + State.uBidiLevel = 0; + hr = ScriptItemize(test5, 38, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); + + State.uBidiLevel = 1; + hr = ScriptItemize(test5, 38, 10, &Control, &State, items, &nItems); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(nItems == 1, "Wrong number of items\n"); + ok(items[0].iCharPos == 0, "Wrong CharPos \n"); + ok(items[0].a.fRTL == 1, "Wrong fRTL\n"); + ok(items[0].a.fLayoutRTL == 1, "Wrong fLayoutRTL\n"); + ok(items[0].a.s.uBidiLevel == 1, "Wrong BidiLevel\n"); +} + + +static void test_ScriptShape(HDC hdc) +{ + static const WCHAR test1[] = {'w', 'i', 'n', 'e',0}; + static const WCHAR test2[] = {0x202B, 'i', 'n', 0x202C,0}; HRESULT hr; SCRIPT_CACHE sc = NULL; - WORD glyphs[4], logclust[4]; + WORD glyphs[4], glyphs2[4], logclust[4]; SCRIPT_VISATTR attrs[4]; SCRIPT_ITEM items[2]; - int nb, widths[4]; - GOFFSET offset[4]; - ABC abc[4]; - - hr = ScriptItemize(NULL, 4, 2, NULL, NULL, items, NULL); - ok(hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG not %08x\n", hr); - - hr = ScriptItemize(test1, 4, 2, NULL, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG not %08x\n", hr); + int nb; hr = ScriptItemize(test1, 4, 2, NULL, NULL, items, NULL); ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); @@ -73,8 +322,122 @@ static void test_ScriptShape(HDC hdc) ok(!hr, "ScriptShape should return S_OK not %08x\n", hr); ok(items[0].a.fNoGlyphIndex == FALSE, "fNoGlyphIndex TRUE\n"); + + memset(glyphs,-1,sizeof(glyphs)); + memset(logclust,-1,sizeof(logclust)); + memset(attrs,-1,sizeof(attrs)); hr = ScriptShape(NULL, &sc, test1, 4, 4, &items[0].a, glyphs, logclust, attrs, &nb); ok(!hr, "ScriptShape should return S_OK not %08x\n", hr); + ok(nb == 4, "Wrong number of items\n"); + ok(logclust[0] == 0, "clusters out of order\n"); + ok(logclust[1] == 1, "clusters out of order\n"); + ok(logclust[2] == 2, "clusters out of order\n"); + ok(logclust[3] == 3, "clusters out of order\n"); + ok(attrs[0].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[1].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[2].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[3].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[0].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[1].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[2].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[3].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[0].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[1].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[2].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[3].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[0].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[1].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[2].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[3].fZeroWidth == 0, "fZeroWidth incorrect\n"); + + ScriptFreeCache(&sc); + sc = NULL; + + memset(glyphs2,-1,sizeof(glyphs2)); + memset(logclust,-1,sizeof(logclust)); + memset(attrs,-1,sizeof(attrs)); + hr = ScriptShape(hdc, &sc, test2, 4, 4, &items[0].a, glyphs2, logclust, attrs, &nb); + ok(hr == S_OK, "ScriptShape should return S_OK not %08x\n", hr); + ok(nb == 4, "Wrong number of items\n"); + ok(glyphs2[0] == 0, "Incorrect glyph for 0x202B\n"); + ok(glyphs2[3] == 0, "Incorrect glyph for 0x202C\n"); + ok(logclust[0] == 0, "clusters out of order\n"); + ok(logclust[1] == 1, "clusters out of order\n"); + ok(logclust[2] == 2, "clusters out of order\n"); + ok(logclust[3] == 3, "clusters out of order\n"); + ok(attrs[0].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[1].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[2].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[3].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[0].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[1].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[2].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[3].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[0].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[1].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[2].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[3].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[0].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[1].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[2].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[3].fZeroWidth == 0, "fZeroWidth incorrect\n"); + + /* modify LTR to RTL */ + items[0].a.fRTL = 1; + memset(glyphs2,-1,sizeof(glyphs2)); + memset(logclust,-1,sizeof(logclust)); + memset(attrs,-1,sizeof(attrs)); + hr = ScriptShape(hdc, &sc, test1, 4, 4, &items[0].a, glyphs2, logclust, attrs, &nb); + ok(!hr, "ScriptShape should return S_OK not %08x\n", hr); + ok(nb == 4, "Wrong number of items\n"); + ok(glyphs2[0] == glyphs[3], "Glyphs not reordered properly\n"); + ok(glyphs2[1] == glyphs[2], "Glyphs not reordered properly\n"); + ok(glyphs2[2] == glyphs[1], "Glyphs not reordered properly\n"); + ok(glyphs2[3] == glyphs[0], "Glyphs not reordered properly\n"); + ok(logclust[0] == 3, "clusters out of order\n"); + ok(logclust[1] == 2, "clusters out of order\n"); + ok(logclust[2] == 1, "clusters out of order\n"); + ok(logclust[3] == 0, "clusters out of order\n"); + ok(attrs[0].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[1].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[2].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[3].uJustification == SCRIPT_JUSTIFY_CHARACTER, "uJustification incorrect\n"); + ok(attrs[0].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[1].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[2].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[3].fClusterStart == 1, "fClusterStart incorrect\n"); + ok(attrs[0].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[1].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[2].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[3].fDiacritic == 0, "fDiacritic incorrect\n"); + ok(attrs[0].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[1].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[2].fZeroWidth == 0, "fZeroWidth incorrect\n"); + ok(attrs[3].fZeroWidth == 0, "fZeroWidth incorrect\n"); + + ScriptFreeCache(&sc); +} + +static void test_ScriptPlace(HDC hdc) +{ + static const WCHAR test1[] = {'t', 'e', 's', 't',0}; + BOOL ret; + HRESULT hr; + SCRIPT_CACHE sc = NULL; + WORD glyphs[4], logclust[4]; + SCRIPT_VISATTR attrs[4]; + SCRIPT_ITEM items[2]; + int nb, widths[4]; + GOFFSET offset[4]; + ABC abc[4]; + + hr = ScriptItemize(test1, 4, 2, NULL, NULL, items, NULL); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + ok(items[0].a.fNoGlyphIndex == FALSE, "fNoGlyphIndex TRUE\n"); + + hr = ScriptShape(hdc, &sc, test1, 4, 4, &items[0].a, glyphs, logclust, attrs, &nb); + ok(!hr, "ScriptShape should return S_OK not %08x\n", hr); + ok(items[0].a.fNoGlyphIndex == FALSE, "fNoGlyphIndex TRUE\n"); hr = ScriptPlace(hdc, &sc, glyphs, 4, NULL, &items[0].a, widths, NULL, NULL); ok(hr == E_INVALIDARG, "ScriptPlace should return E_INVALIDARG not %08x\n", hr); @@ -143,28 +506,6 @@ static void test_ScriptItemIzeShapePlace(HDC hdc, unsigned short pwOutGlyphs[256 ok( ppSp[5]->langid == 9, "Langid[5] not = to 9\n"); /* Check a known value to ensure */ /* ptrs work */ - - /* This set of tests are to check that the various edits in ScriptIemize work */ - cInChars = 5; /* Length of test without NULL */ - cMaxItems = 1; /* Check threshold value */ - hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2. Was %d\n", - cMaxItems); - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(NULL, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n"); - - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(TestItem1, 0, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n"); - - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, NULL, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n"); - /* This is a valid test that will cause parsing to take place */ cInChars = 5; cMaxItems = 255; @@ -636,6 +977,78 @@ static void test_ScriptTextOut2(HDC hdc) } } +static void test_ScriptTextOut3(HDC hdc) +{ + HRESULT hr; + + int cInChars; + int cMaxItems; + SCRIPT_ITEM pItem[255]; + int pcItems; + WCHAR TestItem1[] = {' ','\r', 0}; + + SCRIPT_CACHE psc; + int cChars; + int cMaxGlyphs; + unsigned short pwOutGlyphs1[256]; + WORD pwLogClust[256]; + SCRIPT_VISATTR psva[256]; + int pcGlyphs; + int piAdvance[256]; + GOFFSET pGoffset[256]; + ABC pABC[256]; + RECT rect; + + /* This is to ensure that non exisiting glyphs are translated into a valid glyph number */ + cInChars = 2; + cMaxItems = 255; + hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", hr); + /* This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is * + * returned. */ + ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n"); + if (pcItems > 0) + ok (pItem[0].iCharPos == 0 && pItem[2].iCharPos == cInChars, + "Start pos not = 0 (%d) or end pos not = %d (%d)\n", + pItem[0].iCharPos, cInChars, pItem[2].iCharPos); + + /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue + * ie. ScriptItemize has succeeded and that pItem has been set */ + cInChars = 2; + cMaxItems = 255; + if (hr == 0) { + psc = NULL; /* must be null on first call */ + cChars = cInChars; + cMaxGlyphs = cInChars; + cMaxGlyphs = 256; + hr = ScriptShape(hdc, &psc, TestItem1, cChars, + cMaxGlyphs, &pItem[0].a, + pwOutGlyphs1, pwLogClust, psva, &pcGlyphs); + ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs); + if (hr ==0) { + /* Note hdc is needed as glyph info is not yet in psc */ + hr = ScriptPlace(hdc, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance, + pGoffset, pABC); + ok (hr == 0, "Should return 0 not (%08x)\n", hr); + + /* Test Rect Rgn is acceptable */ + rect.top = 10; + rect.bottom = 20; + rect.left = 10; + rect.right = 40; + hr = ScriptTextOut(hdc, &psc, 0, 0, 0, &rect, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs, + piAdvance, NULL, pGoffset); + ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", hr); + + } + /* Clean up and go */ + ScriptFreeCache(&psc); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + } +} + static void test_ScriptXtoX(void) /**************************************************************************************** * This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables * @@ -1078,20 +1491,55 @@ static void test_ScriptGetGlyphABCWidth(HDC hdc) static void test_ScriptLayout(void) { HRESULT hr; - static const BYTE levels[][5] = + static const BYTE levels[][10] = + { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, + { 1, 1, 1, 2, 2, 2, 1, 1, 1, 1 }, + { 2, 2, 2, 1, 1, 1, 2, 2, 2, 2 }, + { 0, 0, 1, 1, 2, 2, 1, 1, 0, 0 }, + { 1, 1, 2, 2, 3, 3, 2, 2, 1, 1 }, + + { 0, 0, 1, 1, 2, 2, 1, 1, 0, 1 }, + { 1, 0, 1, 2, 2, 1, 2, 1, 0, 1 }, + }; + static const int expect_l2v[][10] = { - { 0, 0, 0, 0, 0 }, - { 1, 1, 1, 1, 1 }, - { 2, 2, 2, 2, 2 }, - { 3, 3, 3, 3, 3 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + + { 0, 1, 2, 3, 4, 9, 8 ,7 ,6, 5}, +/**/ { 9, 8, 7, 4, 5, 6, 3 ,2 ,1, 0}, +/**/ { 7, 8, 9, 6, 5, 4, 0 ,1 ,2, 3}, + { 0, 1, 7, 6, 4, 5, 3 ,2 ,8, 9}, + { 9, 8, 2, 3, 5, 4, 6 ,7 ,1, 0}, + + { 0, 1, 7, 6, 4, 5, 3 ,2 ,8, 9}, +/**/ { 0, 1, 7, 5, 6, 4, 3 ,2 ,8, 9}, }; - static const int expect[][5] = + static const int expect_v2l[][10] = { - { 0, 1, 2, 3, 4 }, - { 4, 3, 2, 1, 0 }, - { 0, 1, 2, 3, 4 }, - { 4, 3, 2, 1, 0 } + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + + { 0, 1, 2, 3, 4, 9, 8 ,7 ,6, 5}, + { 9, 8, 7, 6, 3, 4, 5 ,2 ,1, 0}, + { 6, 7, 8, 9, 5, 4, 3 ,0 ,1, 2}, + { 0, 1, 7, 6, 4, 5, 3 ,2 ,8, 9}, + { 9, 8, 2, 3, 5, 4, 6 ,7 ,1, 0}, + + { 0, 1, 7, 6, 4, 5, 3 ,2 ,8, 9}, + { 0, 1, 7, 6, 5, 3, 4 ,2 ,8, 9}, }; + int i, j, vistolog[sizeof(levels[0])], logtovis[sizeof(levels[0])]; hr = ScriptLayout(sizeof(levels[0]), NULL, vistolog, logtovis); @@ -1107,14 +1555,14 @@ static void test_ScriptLayout(void) for (j = 0; j < sizeof(levels[i]); j++) { - ok(expect[i][j] == vistolog[j], + ok(expect_v2l[i][j] == vistolog[j], "failure: levels[%d][%d] = %d, vistolog[%d] = %d\n", i, j, levels[i][j], j, vistolog[j] ); } for (j = 0; j < sizeof(levels[i]); j++) { - ok(expect[i][j] == logtovis[j], + ok(expect_l2v[i][j] == logtovis[j], "failure: levels[%d][%d] = %d, logtovis[%d] = %d\n", i, j, levels[i][j], j, logtovis[j] ); } @@ -1325,15 +1773,18 @@ START_TEST(usp10) hfont = SelectObject(hdc, CreateFontIndirectA(&lf)); + test_ScriptItemize(); test_ScriptItemIzeShapePlace(hdc,pwOutGlyphs); test_ScriptGetCMap(hdc, pwOutGlyphs); test_ScriptCacheGetHeight(hdc); test_ScriptGetGlyphABCWidth(hdc); test_ScriptShape(hdc); + test_ScriptPlace(hdc); test_ScriptGetFontProperties(hdc); test_ScriptTextOut(hdc); test_ScriptTextOut2(hdc); + test_ScriptTextOut3(hdc); test_ScriptXtoX(); test_ScriptString(hdc); test_ScriptStringXtoCP_CPtoX(hdc); diff --git a/rostests/winetests/wininet/ftp.c b/rostests/winetests/wininet/ftp.c index b4de4e184b6..df9c34753d6 100644 --- a/rostests/winetests/wininet/ftp.c +++ b/rostests/winetests/wininet/ftp.c @@ -42,6 +42,7 @@ static BOOL (WINAPI *pFtpCommandA)(HINTERNET,BOOL,DWORD,LPCSTR,DWORD_PTR,HINTERNET*); +static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET,INTERNET_STATUS_CALLBACK); static void test_getfile_no_open(void) @@ -360,6 +361,20 @@ static void test_getfile(HINTERNET hFtp, HINTERNET hConnect) "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError()); } +static void trace_extended_error(DWORD error) +{ + DWORD code, buflen = 0; + + if (error != ERROR_INTERNET_EXTENDED_ERROR) return; + if (!InternetGetLastResponseInfoA(&code, NULL, &buflen) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + char *text = HeapAlloc(GetProcessHeap(), 0, ++buflen); + InternetGetLastResponseInfoA(&code, text, &buflen); + trace("%u %s\n", code, text); + HeapFree(GetProcessHeap(), 0, text); + } +} + static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) { HINTERNET hOpenFile; @@ -414,34 +429,41 @@ static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) if (hOpenFile) { BOOL bRet; + DWORD error; HINTERNET hOpenFile2; HANDLE hFile; /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */ SetLastError(0xdeadbeef); bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); + trace_extended_error(error); SetLastError(0xdeadbeef); bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); + trace_extended_error(error); SetLastError(0xdeadbeef); bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0); - ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + error = GetLastError(); + ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpGetFileA to fail\n"); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */ SetLastError(0xdeadbeef); hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0); - ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + error = GetLastError(); + ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpOpenFileA to fail\n"); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); InternetCloseHandle(hOpenFile2); /* Just in case */ /* Create a temporary local file */ @@ -451,22 +473,25 @@ static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) CloseHandle(hFile); SetLastError(0xdeadbeef); bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); DeleteFileA("now_existing_local"); SetLastError(0xdeadbeef); bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); SetLastError(0xdeadbeef); bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); } InternetCloseHandle(hOpenFile); @@ -728,6 +753,7 @@ static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect) HINTERNET hSearch; HINTERNET hSearch2; HINTERNET hOpenFile; + DWORD error; /* NULL as the search file ought to return the first file in the directory */ SetLastError(0xdeadbeef); @@ -773,10 +799,17 @@ static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect) /* This should fail as the OpenFile handle wasn't closed */ SetLastError(0xdeadbeef); hSearch = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0); - ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" ); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError() ); - InternetCloseHandle(hSearch); /* Just in case */ + error = GetLastError(); + ok ( hSearch == NULL || broken(hSearch != NULL), /* win2k */ + "Expected FtpFindFirstFileA to fail\n" ); + if (!hSearch) + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error ); + else + { + ok( error == ERROR_SUCCESS, "wrong error %u on success\n", GetLastError() ); + InternetCloseHandle(hSearch); + } InternetCloseHandle(hOpenFile); @@ -889,6 +922,51 @@ static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect) ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError()); } +static void WINAPI status_callback(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD info_len) +{ + switch (status) + { + case INTERNET_STATUS_RESOLVING_NAME: + case INTERNET_STATUS_NAME_RESOLVED: + case INTERNET_STATUS_CONNECTING_TO_SERVER: + case INTERNET_STATUS_CONNECTED_TO_SERVER: + trace("%p %lx %u %s %u\n", handle, ctx, status, (char *)info, info_len); + break; + default: + break; + } +} + +static void test_status_callbacks(HINTERNET hInternet) +{ + INTERNET_STATUS_CALLBACK cb; + HINTERNET hFtp; + BOOL ret; + + if (!pInternetSetStatusCallbackA) + { + win_skip("InternetSetStatusCallbackA() is not available, skipping test\n"); + return; + } + + cb = pInternetSetStatusCallbackA(hInternet, status_callback); + ok(cb == NULL, "expected NULL got %p\n", cb); + + hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, + INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 1); + if (!hFtp) + { + skip("No ftp connection could be made to ftp.winehq.org %u\n", GetLastError()); + return; + } + + ret = InternetCloseHandle(hFtp); + ok(ret, "InternetCloseHandle failed %u\n", GetLastError()); + + cb = pInternetSetStatusCallbackA(hInternet, NULL); + ok(cb == status_callback, "expected check_status got %p\n", cb); +} + START_TEST(ftp) { HMODULE hWininet; @@ -896,6 +974,7 @@ START_TEST(ftp) hWininet = GetModuleHandleA("wininet.dll"); pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA"); + pInternetSetStatusCallbackA = (void*)GetProcAddress(hWininet, "InternetSetStatusCallbackA"); SetLastError(0xdeadbeef); hInternet = InternetOpen("winetest", 0, NULL, NULL, 0); @@ -937,6 +1016,7 @@ START_TEST(ftp) test_command(hFtp, hHttp); test_find_first_file(hFtp, hHttp); test_get_current_dir(hFtp, hHttp); + test_status_callbacks(hInternet); InternetCloseHandle(hHttp); InternetCloseHandle(hFtp); diff --git a/rostests/winetests/wininet/generated.c b/rostests/winetests/wininet/generated.c index ceb21deb869..1282b6fda5e 100644 --- a/rostests/winetests/wininet/generated.c +++ b/rostests/winetests/wininet/generated.c @@ -55,45 +55,1272 @@ * Test helper macros */ +#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); + +#ifdef TYPE_ALIGNMENT +# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); +#else +# define TEST_TYPE_ALIGN(type, align) +#endif + +#ifdef _TYPE_ALIGNMENT +# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); +# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); +#else +# define TEST_TARGET_ALIGN(type, align) +# define TEST_FIELD_ALIGN(type, field, align) +#endif + +#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); + +#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) +#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) +#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); +#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); + + #ifdef _WIN64 -# define TEST_TYPE_SIZE(type, size) -# define TEST_TYPE_ALIGN(type, align) -# define TEST_TARGET_ALIGN(type, align) -# define TEST_FIELD_ALIGN(type, field, align) -# define TEST_FIELD_OFFSET(type, field, offset) +static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 16) + TEST_TYPE_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, ShortAbstract, 8) + TEST_FIELD_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, ShortAbstract, 8) + TEST_FIELD_OFFSET(GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, ShortAbstract, 0) + TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, AbstractFile, 8) + TEST_FIELD_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, AbstractFile, 8) + TEST_FIELD_OFFSET(GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, AbstractFile, 8) +} + +static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 16) + TEST_TYPE_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, ShortAbstract, 8) + TEST_FIELD_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, ShortAbstract, 8) + TEST_FIELD_OFFSET(GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, ShortAbstract, 0) + TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, AbstractFile, 8) + TEST_FIELD_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, AbstractFile, 8) + TEST_FIELD_OFFSET(GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, AbstractFile, 8) +} + +static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_ADMIN_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEA, 16) + TEST_TYPE_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEA, Comment, 8) + TEST_FIELD_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEA, Comment, 8) + TEST_FIELD_OFFSET(GOPHER_ADMIN_ATTRIBUTE_TYPEA, Comment, 0) + TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEA, EmailAddress, 8) + TEST_FIELD_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEA, EmailAddress, 8) + TEST_FIELD_OFFSET(GOPHER_ADMIN_ATTRIBUTE_TYPEA, EmailAddress, 8) +} + +static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_ADMIN_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEW, 16) + TEST_TYPE_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEW, Comment, 8) + TEST_FIELD_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEW, Comment, 8) + TEST_FIELD_OFFSET(GOPHER_ADMIN_ATTRIBUTE_TYPEW, Comment, 0) + TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEW, EmailAddress, 8) + TEST_FIELD_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEW, EmailAddress, 8) + TEST_FIELD_OFFSET(GOPHER_ADMIN_ATTRIBUTE_TYPEW, EmailAddress, 8) +} + +static void test_pack_GOPHER_ASK_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_ASK_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEA, 16) + TEST_TYPE_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionType, 8) + TEST_FIELD_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionType, 8) + TEST_FIELD_OFFSET(GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionType, 0) + TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionText, 8) + TEST_FIELD_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionText, 8) + TEST_FIELD_OFFSET(GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionText, 8) +} + +static void test_pack_GOPHER_ASK_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_ASK_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEW, 16) + TEST_TYPE_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionType, 8) + TEST_FIELD_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionType, 8) + TEST_FIELD_OFFSET(GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionType, 0) + TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionText, 8) + TEST_FIELD_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionText, 8) + TEST_FIELD_OFFSET(GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionText, 8) +} + +static void test_pack_GOPHER_ATTRIBUTE_ENUMERATORA(void) +{ + /* GOPHER_ATTRIBUTE_ENUMERATORA */ + TEST_TYPE_SIZE (GOPHER_ATTRIBUTE_ENUMERATORA, 8) + TEST_TYPE_ALIGN (GOPHER_ATTRIBUTE_ENUMERATORA, 8) +} + +static void test_pack_GOPHER_ATTRIBUTE_ENUMERATORW(void) +{ + /* GOPHER_ATTRIBUTE_ENUMERATORW */ + TEST_TYPE_SIZE (GOPHER_ATTRIBUTE_ENUMERATORW, 8) + TEST_TYPE_ALIGN (GOPHER_ATTRIBUTE_ENUMERATORW, 8) +} + +static void test_pack_GOPHER_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_ATTRIBUTE_TYPEA */ + TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEA, CategoryId, 4) + TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEA, CategoryId, 4) + TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEA, CategoryId, 0) + TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEA, AttributeId, 4) + TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEA, AttributeId, 4) + TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEA, AttributeId, 4) +} + +static void test_pack_GOPHER_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_ATTRIBUTE_TYPEW */ + TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEW, CategoryId, 4) + TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEW, CategoryId, 4) + TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEW, CategoryId, 0) + TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEW, AttributeId, 4) + TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEW, AttributeId, 4) + TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEW, AttributeId, 4) +} + +static void test_pack_GOPHER_FIND_DATAA(void) +{ + /* GOPHER_FIND_DATAA */ + TEST_TYPE_SIZE (GOPHER_FIND_DATAA, 808) + TEST_TYPE_ALIGN (GOPHER_FIND_DATAA, 4) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, DisplayString, 129) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, DisplayString, 1) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, DisplayString, 0) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, GopherType, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, GopherType, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, GopherType, 132) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, SizeLow, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, SizeLow, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, SizeLow, 136) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, SizeHigh, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, SizeHigh, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, SizeHigh, 140) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, LastModificationTime, 8) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, LastModificationTime, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, LastModificationTime, 144) + TEST_FIELD_SIZE (GOPHER_FIND_DATAA, Locator, 654) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAA, Locator, 1) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAA, Locator, 152) +} + +static void test_pack_GOPHER_FIND_DATAW(void) +{ + /* GOPHER_FIND_DATAW */ + TEST_TYPE_SIZE (GOPHER_FIND_DATAW, 1588) + TEST_TYPE_ALIGN (GOPHER_FIND_DATAW, 4) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, DisplayString, 258) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, DisplayString, 2) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, DisplayString, 0) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, GopherType, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, GopherType, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, GopherType, 260) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, SizeLow, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, SizeLow, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, SizeLow, 264) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, SizeHigh, 4) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, SizeHigh, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, SizeHigh, 268) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, LastModificationTime, 8) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, LastModificationTime, 4) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, LastModificationTime, 272) + TEST_FIELD_SIZE (GOPHER_FIND_DATAW, Locator, 1308) + TEST_FIELD_ALIGN (GOPHER_FIND_DATAW, Locator, 2) + TEST_FIELD_OFFSET(GOPHER_FIND_DATAW, Locator, 280) +} + +static void test_pack_GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 24) + TEST_TYPE_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesNorth, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesNorth, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesNorth, 0) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesNorth, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesNorth, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesNorth, 4) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsNorth, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsNorth, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsNorth, 8) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesEast, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesEast, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesEast, 12) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesEast, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesEast, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, MinutesEast, 16) + TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsEast, 4) + TEST_FIELD_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsEast, 4) + TEST_FIELD_OFFSET(GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, SecondsEast, 20) +} + +static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_LOCATION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEA, Location, 8) + TEST_FIELD_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEA, Location, 8) + TEST_FIELD_OFFSET(GOPHER_LOCATION_ATTRIBUTE_TYPEA, Location, 0) +} + +static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_LOCATION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEW, Location, 8) + TEST_FIELD_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEW, Location, 8) + TEST_FIELD_OFFSET(GOPHER_LOCATION_ATTRIBUTE_TYPEW, Location, 0) +} + +static void test_pack_GOPHER_MOD_DATE_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_MOD_DATE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, DateAndTime, 8) + TEST_FIELD_ALIGN (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, DateAndTime, 4) + TEST_FIELD_OFFSET(GOPHER_MOD_DATE_ATTRIBUTE_TYPE, DateAndTime, 0) +} + +static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, Organization, 8) + TEST_FIELD_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, Organization, 8) + TEST_FIELD_OFFSET(GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, Organization, 0) +} + +static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, Organization, 8) + TEST_FIELD_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, Organization, 8) + TEST_FIELD_OFFSET(GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, Organization, 0) +} + +static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_PROVIDER_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, Provider, 8) + TEST_FIELD_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, Provider, 8) + TEST_FIELD_OFFSET(GOPHER_PROVIDER_ATTRIBUTE_TYPEA, Provider, 0) +} + +static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_PROVIDER_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, Provider, 8) + TEST_FIELD_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, Provider, 8) + TEST_FIELD_OFFSET(GOPHER_PROVIDER_ATTRIBUTE_TYPEW, Provider, 0) +} + +static void test_pack_GOPHER_SCORE_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_SCORE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_SCORE_ATTRIBUTE_TYPE, 4) + TEST_TYPE_ALIGN (GOPHER_SCORE_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_SCORE_ATTRIBUTE_TYPE, Score, 4) + TEST_FIELD_ALIGN (GOPHER_SCORE_ATTRIBUTE_TYPE, Score, 4) + TEST_FIELD_OFFSET(GOPHER_SCORE_ATTRIBUTE_TYPE, Score, 0) +} + +static void test_pack_GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, LowerBound, 4) + TEST_FIELD_ALIGN (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, LowerBound, 4) + TEST_FIELD_OFFSET(GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, LowerBound, 0) + TEST_FIELD_SIZE (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, UpperBound, 4) + TEST_FIELD_ALIGN (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, UpperBound, 4) + TEST_FIELD_OFFSET(GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, UpperBound, 4) +} + +static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_SITE_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEA, Site, 8) + TEST_FIELD_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEA, Site, 8) + TEST_FIELD_OFFSET(GOPHER_SITE_ATTRIBUTE_TYPEA, Site, 0) +} + +static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_SITE_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEW, Site, 8) + TEST_FIELD_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEW, Site, 8) + TEST_FIELD_OFFSET(GOPHER_SITE_ATTRIBUTE_TYPEW, Site, 0) +} + +static void test_pack_GOPHER_TIMEZONE_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_TIMEZONE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) + TEST_TYPE_ALIGN (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, Zone, 4) + TEST_FIELD_ALIGN (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, Zone, 4) + TEST_FIELD_OFFSET(GOPHER_TIMEZONE_ATTRIBUTE_TYPE, Zone, 0) +} + +static void test_pack_GOPHER_TTL_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_TTL_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_TTL_ATTRIBUTE_TYPE, 4) + TEST_TYPE_ALIGN (GOPHER_TTL_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_TTL_ATTRIBUTE_TYPE, Ttl, 4) + TEST_FIELD_ALIGN (GOPHER_TTL_ATTRIBUTE_TYPE, Ttl, 4) + TEST_FIELD_OFFSET(GOPHER_TTL_ATTRIBUTE_TYPE, Ttl, 0) +} + +static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, Text, 8) + TEST_FIELD_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, Text, 8) + TEST_FIELD_OFFSET(GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, Text, 0) +} + +static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, Text, 8) + TEST_FIELD_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, Text, 8) + TEST_FIELD_OFFSET(GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, Text, 0) +} + +static void test_pack_GOPHER_VERONICA_ATTRIBUTE_TYPE(void) +{ + /* GOPHER_VERONICA_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (GOPHER_VERONICA_ATTRIBUTE_TYPE, 4) + TEST_TYPE_ALIGN (GOPHER_VERONICA_ATTRIBUTE_TYPE, 4) + TEST_FIELD_SIZE (GOPHER_VERONICA_ATTRIBUTE_TYPE, TreeWalk, 4) + TEST_FIELD_ALIGN (GOPHER_VERONICA_ATTRIBUTE_TYPE, TreeWalk, 4) + TEST_FIELD_OFFSET(GOPHER_VERONICA_ATTRIBUTE_TYPE, TreeWalk, 0) +} + +static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_VERSION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEA, Version, 8) + TEST_FIELD_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEA, Version, 8) + TEST_FIELD_OFFSET(GOPHER_VERSION_ATTRIBUTE_TYPEA, Version, 0) +} + +static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_VERSION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEW, Version, 8) + TEST_FIELD_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEW, Version, 8) + TEST_FIELD_OFFSET(GOPHER_VERSION_ATTRIBUTE_TYPEW, Version, 0) +} + +static void test_pack_GOPHER_VIEW_ATTRIBUTE_TYPEA(void) +{ + /* GOPHER_VIEW_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, 24) + TEST_TYPE_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEA, 8) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, ContentType, 8) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEA, ContentType, 8) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEA, ContentType, 0) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, Language, 8) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEA, Language, 8) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEA, Language, 8) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, Size, 4) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEA, Size, 4) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEA, Size, 16) +} + +static void test_pack_GOPHER_VIEW_ATTRIBUTE_TYPEW(void) +{ + /* GOPHER_VIEW_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, 24) + TEST_TYPE_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEW, 8) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, ContentType, 8) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEW, ContentType, 8) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEW, ContentType, 0) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, Language, 8) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEW, Language, 8) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEW, Language, 8) + TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, Size, 4) + TEST_FIELD_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEW, Size, 4) + TEST_FIELD_OFFSET(GOPHER_VIEW_ATTRIBUTE_TYPEW, Size, 16) +} + +static void test_pack_GROUPID(void) +{ + /* GROUPID */ + TEST_TYPE_SIZE (GROUPID, 8) + TEST_TYPE_ALIGN (GROUPID, 8) + TEST_TYPE_SIGNED(GROUPID) +} + +static void test_pack_HINTERNET(void) +{ + /* HINTERNET */ + TEST_TYPE_SIZE (HINTERNET, 8) + TEST_TYPE_ALIGN (HINTERNET, 8) +} + +static void test_pack_HTTP_VERSION_INFO(void) +{ + /* HTTP_VERSION_INFO */ + TEST_TYPE_SIZE (HTTP_VERSION_INFO, 8) + TEST_TYPE_ALIGN (HTTP_VERSION_INFO, 4) + TEST_FIELD_SIZE (HTTP_VERSION_INFO, dwMajorVersion, 4) + TEST_FIELD_ALIGN (HTTP_VERSION_INFO, dwMajorVersion, 4) + TEST_FIELD_OFFSET(HTTP_VERSION_INFO, dwMajorVersion, 0) + TEST_FIELD_SIZE (HTTP_VERSION_INFO, dwMinorVersion, 4) + TEST_FIELD_ALIGN (HTTP_VERSION_INFO, dwMinorVersion, 4) + TEST_FIELD_OFFSET(HTTP_VERSION_INFO, dwMinorVersion, 4) +} + +static void test_pack_INTERNET_ASYNC_RESULT(void) +{ + /* INTERNET_ASYNC_RESULT */ + TEST_TYPE_SIZE (INTERNET_ASYNC_RESULT, 16) + TEST_TYPE_ALIGN (INTERNET_ASYNC_RESULT, 8) + TEST_FIELD_SIZE (INTERNET_ASYNC_RESULT, dwResult, 8) + TEST_FIELD_ALIGN (INTERNET_ASYNC_RESULT, dwResult, 8) + TEST_FIELD_OFFSET(INTERNET_ASYNC_RESULT, dwResult, 0) + TEST_FIELD_SIZE (INTERNET_ASYNC_RESULT, dwError, 4) + TEST_FIELD_ALIGN (INTERNET_ASYNC_RESULT, dwError, 4) + TEST_FIELD_OFFSET(INTERNET_ASYNC_RESULT, dwError, 8) +} + +static void test_pack_INTERNET_AUTH_NOTIFY_DATA(void) +{ + /* INTERNET_AUTH_NOTIFY_DATA */ + TEST_TYPE_SIZE (INTERNET_AUTH_NOTIFY_DATA, 24) + TEST_TYPE_ALIGN (INTERNET_AUTH_NOTIFY_DATA, 8) + TEST_FIELD_SIZE (INTERNET_AUTH_NOTIFY_DATA, cbStruct, 4) + TEST_FIELD_ALIGN (INTERNET_AUTH_NOTIFY_DATA, cbStruct, 4) + TEST_FIELD_OFFSET(INTERNET_AUTH_NOTIFY_DATA, cbStruct, 0) + TEST_FIELD_SIZE (INTERNET_AUTH_NOTIFY_DATA, dwOptions, 4) + TEST_FIELD_ALIGN (INTERNET_AUTH_NOTIFY_DATA, dwOptions, 4) + TEST_FIELD_OFFSET(INTERNET_AUTH_NOTIFY_DATA, dwOptions, 4) + TEST_FIELD_SIZE (INTERNET_AUTH_NOTIFY_DATA, pfnNotify, 8) + TEST_FIELD_ALIGN (INTERNET_AUTH_NOTIFY_DATA, pfnNotify, 8) + TEST_FIELD_OFFSET(INTERNET_AUTH_NOTIFY_DATA, pfnNotify, 8) + TEST_FIELD_SIZE (INTERNET_AUTH_NOTIFY_DATA, dwContext, 8) + TEST_FIELD_ALIGN (INTERNET_AUTH_NOTIFY_DATA, dwContext, 8) + TEST_FIELD_OFFSET(INTERNET_AUTH_NOTIFY_DATA, dwContext, 16) +} + +static void test_pack_INTERNET_BUFFERSA(void) +{ + /* INTERNET_BUFFERSA */ + TEST_TYPE_SIZE (INTERNET_BUFFERSA, 56) + TEST_TYPE_ALIGN (INTERNET_BUFFERSA, 8) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwStructSize, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwStructSize, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwStructSize, 0) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, Next, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, Next, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, Next, 8) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, lpcszHeader, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, lpcszHeader, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, lpcszHeader, 16) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwHeadersLength, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwHeadersLength, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwHeadersLength, 24) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwHeadersTotal, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwHeadersTotal, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwHeadersTotal, 28) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, lpvBuffer, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, lpvBuffer, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, lpvBuffer, 32) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwBufferLength, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwBufferLength, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwBufferLength, 40) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwBufferTotal, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwBufferTotal, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwBufferTotal, 44) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwOffsetLow, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwOffsetLow, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwOffsetLow, 48) + TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwOffsetHigh, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSA, dwOffsetHigh, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSA, dwOffsetHigh, 52) +} + +static void test_pack_INTERNET_BUFFERSW(void) +{ + /* INTERNET_BUFFERSW */ + TEST_TYPE_SIZE (INTERNET_BUFFERSW, 56) + TEST_TYPE_ALIGN (INTERNET_BUFFERSW, 8) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwStructSize, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwStructSize, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwStructSize, 0) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, Next, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, Next, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, Next, 8) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, lpcszHeader, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, lpcszHeader, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, lpcszHeader, 16) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwHeadersLength, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwHeadersLength, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwHeadersLength, 24) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwHeadersTotal, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwHeadersTotal, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwHeadersTotal, 28) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, lpvBuffer, 8) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, lpvBuffer, 8) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, lpvBuffer, 32) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwBufferLength, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwBufferLength, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwBufferLength, 40) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwBufferTotal, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwBufferTotal, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwBufferTotal, 44) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwOffsetLow, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwOffsetLow, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwOffsetLow, 48) + TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwOffsetHigh, 4) + TEST_FIELD_ALIGN (INTERNET_BUFFERSW, dwOffsetHigh, 4) + TEST_FIELD_OFFSET(INTERNET_BUFFERSW, dwOffsetHigh, 52) +} + +static void test_pack_INTERNET_CACHE_ENTRY_INFOA(void) +{ + /* INTERNET_CACHE_ENTRY_INFOA */ + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 0) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, lpszSourceUrlName, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, lpszSourceUrlName, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, lpszSourceUrlName, 8) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, lpszLocalFileName, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, lpszLocalFileName, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, lpszLocalFileName, 16) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, CacheEntryType, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, CacheEntryType, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, CacheEntryType, 24) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwUseCount, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwUseCount, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwUseCount, 28) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwHitRate, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwHitRate, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwHitRate, 32) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwSizeLow, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwSizeLow, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwSizeLow, 36) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwSizeHigh, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwSizeHigh, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwSizeHigh, 40) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, LastModifiedTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, LastModifiedTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, LastModifiedTime, 44) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, ExpireTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, ExpireTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, ExpireTime, 52) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, LastAccessTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, LastAccessTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, LastAccessTime, 60) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, LastSyncTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, LastSyncTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, LastSyncTime, 68) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, lpHeaderInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, lpHeaderInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, lpHeaderInfo, 80) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwHeaderInfoSize, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwHeaderInfoSize, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwHeaderInfoSize, 88) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, lpszFileExtension, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, lpszFileExtension, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, lpszFileExtension, 96) +} + +static void test_pack_INTERNET_CACHE_ENTRY_INFOW(void) +{ + /* INTERNET_CACHE_ENTRY_INFOW */ + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 0) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, lpszSourceUrlName, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, lpszSourceUrlName, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, lpszSourceUrlName, 8) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, lpszLocalFileName, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, lpszLocalFileName, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, lpszLocalFileName, 16) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, CacheEntryType, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, CacheEntryType, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, CacheEntryType, 24) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwUseCount, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwUseCount, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwUseCount, 28) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwHitRate, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwHitRate, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwHitRate, 32) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwSizeLow, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwSizeLow, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwSizeLow, 36) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwSizeHigh, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwSizeHigh, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwSizeHigh, 40) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, LastModifiedTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, LastModifiedTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, LastModifiedTime, 44) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, ExpireTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, ExpireTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, ExpireTime, 52) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, LastAccessTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, LastAccessTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, LastAccessTime, 60) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, LastSyncTime, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, LastSyncTime, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, LastSyncTime, 68) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, lpHeaderInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, lpHeaderInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, lpHeaderInfo, 80) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwHeaderInfoSize, 4) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwHeaderInfoSize, 4) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwHeaderInfoSize, 88) + TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, lpszFileExtension, 8) + TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, lpszFileExtension, 8) + TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, lpszFileExtension, 96) +} + +static void test_pack_INTERNET_CERTIFICATE_INFOA(void) +{ + /* INTERNET_CERTIFICATE_INFOA */ + TEST_TYPE_SIZE (INTERNET_CERTIFICATE_INFOA, 64) + TEST_TYPE_ALIGN (INTERNET_CERTIFICATE_INFOA, 8) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, ftExpiry, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, ftExpiry, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, ftExpiry, 0) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, ftStart, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, ftStart, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, ftStart, 8) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, lpszSubjectInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, lpszSubjectInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, lpszSubjectInfo, 16) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, lpszIssuerInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, lpszIssuerInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, lpszIssuerInfo, 24) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, lpszProtocolName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, lpszProtocolName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, lpszProtocolName, 32) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, lpszSignatureAlgName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, lpszSignatureAlgName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, lpszSignatureAlgName, 40) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, lpszEncryptionAlgName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, lpszEncryptionAlgName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, lpszEncryptionAlgName, 48) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, dwKeySize, 4) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOA, dwKeySize, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOA, dwKeySize, 56) +} + +static void test_pack_INTERNET_CERTIFICATE_INFOW(void) +{ + /* INTERNET_CERTIFICATE_INFOW */ + TEST_TYPE_SIZE (INTERNET_CERTIFICATE_INFOW, 64) + TEST_TYPE_ALIGN (INTERNET_CERTIFICATE_INFOW, 8) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, ftExpiry, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, ftExpiry, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, ftExpiry, 0) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, ftStart, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, ftStart, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, ftStart, 8) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, lpszSubjectInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, lpszSubjectInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, lpszSubjectInfo, 16) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, lpszIssuerInfo, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, lpszIssuerInfo, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, lpszIssuerInfo, 24) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, lpszProtocolName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, lpszProtocolName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, lpszProtocolName, 32) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, lpszSignatureAlgName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, lpszSignatureAlgName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, lpszSignatureAlgName, 40) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, lpszEncryptionAlgName, 8) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, lpszEncryptionAlgName, 8) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, lpszEncryptionAlgName, 48) + TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, dwKeySize, 4) + TEST_FIELD_ALIGN (INTERNET_CERTIFICATE_INFOW, dwKeySize, 4) + TEST_FIELD_OFFSET(INTERNET_CERTIFICATE_INFOW, dwKeySize, 56) +} + +static void test_pack_INTERNET_CONNECTED_INFO(void) +{ + /* INTERNET_CONNECTED_INFO */ + TEST_TYPE_SIZE (INTERNET_CONNECTED_INFO, 8) + TEST_TYPE_ALIGN (INTERNET_CONNECTED_INFO, 4) + TEST_FIELD_SIZE (INTERNET_CONNECTED_INFO, dwConnectedState, 4) + TEST_FIELD_ALIGN (INTERNET_CONNECTED_INFO, dwConnectedState, 4) + TEST_FIELD_OFFSET(INTERNET_CONNECTED_INFO, dwConnectedState, 0) + TEST_FIELD_SIZE (INTERNET_CONNECTED_INFO, dwFlags, 4) + TEST_FIELD_ALIGN (INTERNET_CONNECTED_INFO, dwFlags, 4) + TEST_FIELD_OFFSET(INTERNET_CONNECTED_INFO, dwFlags, 4) +} + +static void test_pack_INTERNET_PORT(void) +{ + /* INTERNET_PORT */ + TEST_TYPE_SIZE (INTERNET_PORT, 2) + TEST_TYPE_ALIGN (INTERNET_PORT, 2) + TEST_TYPE_UNSIGNED(INTERNET_PORT) +} + +static void test_pack_INTERNET_PROXY_INFOA(void) +{ + /* INTERNET_PROXY_INFOA */ + TEST_TYPE_SIZE (INTERNET_PROXY_INFOA, 24) + TEST_TYPE_ALIGN (INTERNET_PROXY_INFOA, 8) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOA, dwAccessType, 4) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOA, dwAccessType, 4) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOA, dwAccessType, 0) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOA, lpszProxy, 8) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOA, lpszProxy, 8) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOA, lpszProxy, 8) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOA, lpszProxyBypass, 8) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOA, lpszProxyBypass, 8) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOA, lpszProxyBypass, 16) +} + +static void test_pack_INTERNET_PROXY_INFOW(void) +{ + /* INTERNET_PROXY_INFOW */ + TEST_TYPE_SIZE (INTERNET_PROXY_INFOW, 24) + TEST_TYPE_ALIGN (INTERNET_PROXY_INFOW, 8) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOW, dwAccessType, 4) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOW, dwAccessType, 4) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOW, dwAccessType, 0) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOW, lpszProxy, 8) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOW, lpszProxy, 8) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOW, lpszProxy, 8) + TEST_FIELD_SIZE (INTERNET_PROXY_INFOW, lpszProxyBypass, 8) + TEST_FIELD_ALIGN (INTERNET_PROXY_INFOW, lpszProxyBypass, 8) + TEST_FIELD_OFFSET(INTERNET_PROXY_INFOW, lpszProxyBypass, 16) +} + +static void test_pack_INTERNET_STATUS_CALLBACK(void) +{ + /* INTERNET_STATUS_CALLBACK */ + TEST_TYPE_SIZE (INTERNET_STATUS_CALLBACK, 8) + TEST_TYPE_ALIGN (INTERNET_STATUS_CALLBACK, 8) +} + +static void test_pack_INTERNET_VERSION_INFO(void) +{ + /* INTERNET_VERSION_INFO */ + TEST_TYPE_SIZE (INTERNET_VERSION_INFO, 8) + TEST_TYPE_ALIGN (INTERNET_VERSION_INFO, 4) + TEST_FIELD_SIZE (INTERNET_VERSION_INFO, dwMajorVersion, 4) + TEST_FIELD_ALIGN (INTERNET_VERSION_INFO, dwMajorVersion, 4) + TEST_FIELD_OFFSET(INTERNET_VERSION_INFO, dwMajorVersion, 0) + TEST_FIELD_SIZE (INTERNET_VERSION_INFO, dwMinorVersion, 4) + TEST_FIELD_ALIGN (INTERNET_VERSION_INFO, dwMinorVersion, 4) + TEST_FIELD_OFFSET(INTERNET_VERSION_INFO, dwMinorVersion, 4) +} + +static void test_pack_LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 16) + TEST_TARGET_ALIGN(LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 16) + TEST_TARGET_ALIGN(LPGOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_ADMIN_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_ADMIN_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_ADMIN_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_ADMIN_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_ADMIN_ATTRIBUTE_TYPEA, 16) + TEST_TARGET_ALIGN(LPGOPHER_ADMIN_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_ADMIN_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_ADMIN_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_ADMIN_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_ADMIN_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_ADMIN_ATTRIBUTE_TYPEW, 16) + TEST_TARGET_ALIGN(LPGOPHER_ADMIN_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_ASK_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_ASK_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_ASK_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_ASK_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_ASK_ATTRIBUTE_TYPEA, 16) + TEST_TARGET_ALIGN(LPGOPHER_ASK_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_ASK_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_ASK_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_ASK_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_ASK_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_ASK_ATTRIBUTE_TYPEW, 16) + TEST_TARGET_ALIGN(LPGOPHER_ASK_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_FIND_DATAA(void) +{ + /* LPGOPHER_FIND_DATAA */ + TEST_TYPE_SIZE (LPGOPHER_FIND_DATAA, 8) + TEST_TYPE_ALIGN (LPGOPHER_FIND_DATAA, 8) + TEST_TARGET_SIZE (LPGOPHER_FIND_DATAA, 808) + TEST_TARGET_ALIGN(LPGOPHER_FIND_DATAA, 4) +} + +static void test_pack_LPGOPHER_FIND_DATAW(void) +{ + /* LPGOPHER_FIND_DATAW */ + TEST_TYPE_SIZE (LPGOPHER_FIND_DATAW, 8) + TEST_TYPE_ALIGN (LPGOPHER_FIND_DATAW, 8) + TEST_TARGET_SIZE (LPGOPHER_FIND_DATAW, 1588) + TEST_TARGET_ALIGN(LPGOPHER_FIND_DATAW, 4) +} -#else +static void test_pack_LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 24) + TEST_TARGET_ALIGN(LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 4) +} + +static void test_pack_LPGOPHER_LOCATION_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_LOCATION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_LOCATION_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_LOCATION_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_LOCATION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_LOCATION_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_ALIGN(LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE, 4) +} -# define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); +static void test_pack_LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 8) +} -# ifdef TYPE_ALIGNMENT -# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); -# else -# define TEST_TYPE_ALIGN(type, align) -# endif +static void test_pack_LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 8) +} -# ifdef _TYPE_ALIGNMENT -# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); -# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); -# else -# define TEST_TARGET_ALIGN(type, align) -# define TEST_FIELD_ALIGN(type, field, align) -# endif +static void test_pack_LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_PROVIDER_ATTRIBUTE_TYPEA, 8) +} -# define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); +static void test_pack_LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_PROVIDER_ATTRIBUTE_TYPEW, 8) +} -#endif +static void test_pack_LPGOPHER_SCORE_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_SCORE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_SCORE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_SCORE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_SCORE_ATTRIBUTE_TYPE, 4) + TEST_TARGET_ALIGN(LPGOPHER_SCORE_ATTRIBUTE_TYPE, 4) +} -#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) -#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) -#define TEST_TYPE_SIGNED(type) C_ASSERT((type) -1 < 0); -#define TEST_TYPE_UNSIGNED(type) C_ASSERT((type) -1 > 0); +static void test_pack_LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_ALIGN(LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 4) +} + +static void test_pack_LPGOPHER_SITE_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_SITE_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_SITE_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_SITE_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_SITE_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_SITE_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_SITE_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_SITE_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_SITE_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_SITE_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_SITE_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_SITE_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) + TEST_TARGET_ALIGN(LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) +} + +static void test_pack_LPGOPHER_TTL_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_TTL_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_TTL_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_TTL_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_TTL_ATTRIBUTE_TYPE, 4) + TEST_TARGET_ALIGN(LPGOPHER_TTL_ATTRIBUTE_TYPE, 4) +} + +static void test_pack_LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_VERONICA_ATTRIBUTE_TYPE(void) +{ + /* LPGOPHER_VERONICA_ATTRIBUTE_TYPE */ + TEST_TYPE_SIZE (LPGOPHER_VERONICA_ATTRIBUTE_TYPE, 8) + TEST_TYPE_ALIGN (LPGOPHER_VERONICA_ATTRIBUTE_TYPE, 8) + TEST_TARGET_SIZE (LPGOPHER_VERONICA_ATTRIBUTE_TYPE, 4) + TEST_TARGET_ALIGN(LPGOPHER_VERONICA_ATTRIBUTE_TYPE, 4) +} + +static void test_pack_LPGOPHER_VERSION_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_VERSION_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_VERSION_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_VERSION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_VERSION_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_ALIGN(LPGOPHER_VERSION_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_VERSION_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_VERSION_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_VERSION_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_VERSION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_VERSION_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_ALIGN(LPGOPHER_VERSION_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPGOPHER_VIEW_ATTRIBUTE_TYPEA(void) +{ + /* LPGOPHER_VIEW_ATTRIBUTE_TYPEA */ + TEST_TYPE_SIZE (LPGOPHER_VIEW_ATTRIBUTE_TYPEA, 8) + TEST_TYPE_ALIGN (LPGOPHER_VIEW_ATTRIBUTE_TYPEA, 8) + TEST_TARGET_SIZE (LPGOPHER_VIEW_ATTRIBUTE_TYPEA, 24) + TEST_TARGET_ALIGN(LPGOPHER_VIEW_ATTRIBUTE_TYPEA, 8) +} + +static void test_pack_LPGOPHER_VIEW_ATTRIBUTE_TYPEW(void) +{ + /* LPGOPHER_VIEW_ATTRIBUTE_TYPEW */ + TEST_TYPE_SIZE (LPGOPHER_VIEW_ATTRIBUTE_TYPEW, 8) + TEST_TYPE_ALIGN (LPGOPHER_VIEW_ATTRIBUTE_TYPEW, 8) + TEST_TARGET_SIZE (LPGOPHER_VIEW_ATTRIBUTE_TYPEW, 24) + TEST_TARGET_ALIGN(LPGOPHER_VIEW_ATTRIBUTE_TYPEW, 8) +} + +static void test_pack_LPHINTERNET(void) +{ + /* LPHINTERNET */ + TEST_TYPE_SIZE (LPHINTERNET, 8) + TEST_TYPE_ALIGN (LPHINTERNET, 8) + TEST_TARGET_SIZE (LPHINTERNET, 8) + TEST_TARGET_ALIGN(LPHINTERNET, 8) +} + +static void test_pack_LPHTTP_VERSION_INFO(void) +{ + /* LPHTTP_VERSION_INFO */ + TEST_TYPE_SIZE (LPHTTP_VERSION_INFO, 8) + TEST_TYPE_ALIGN (LPHTTP_VERSION_INFO, 8) + TEST_TARGET_SIZE (LPHTTP_VERSION_INFO, 8) + TEST_TARGET_ALIGN(LPHTTP_VERSION_INFO, 4) +} + +static void test_pack_LPINTERNET_ASYNC_RESULT(void) +{ + /* LPINTERNET_ASYNC_RESULT */ + TEST_TYPE_SIZE (LPINTERNET_ASYNC_RESULT, 8) + TEST_TYPE_ALIGN (LPINTERNET_ASYNC_RESULT, 8) + TEST_TARGET_SIZE (LPINTERNET_ASYNC_RESULT, 16) + TEST_TARGET_ALIGN(LPINTERNET_ASYNC_RESULT, 8) +} + +static void test_pack_LPINTERNET_BUFFERSA(void) +{ + /* LPINTERNET_BUFFERSA */ + TEST_TYPE_SIZE (LPINTERNET_BUFFERSA, 8) + TEST_TYPE_ALIGN (LPINTERNET_BUFFERSA, 8) + TEST_TARGET_SIZE (LPINTERNET_BUFFERSA, 56) + TEST_TARGET_ALIGN(LPINTERNET_BUFFERSA, 8) +} + +static void test_pack_LPINTERNET_BUFFERSW(void) +{ + /* LPINTERNET_BUFFERSW */ + TEST_TYPE_SIZE (LPINTERNET_BUFFERSW, 8) + TEST_TYPE_ALIGN (LPINTERNET_BUFFERSW, 8) + TEST_TARGET_SIZE (LPINTERNET_BUFFERSW, 56) + TEST_TARGET_ALIGN(LPINTERNET_BUFFERSW, 8) +} + +static void test_pack_LPINTERNET_CACHE_ENTRY_INFOA(void) +{ + /* LPINTERNET_CACHE_ENTRY_INFOA */ + TEST_TYPE_SIZE (LPINTERNET_CACHE_ENTRY_INFOA, 8) + TEST_TYPE_ALIGN (LPINTERNET_CACHE_ENTRY_INFOA, 8) +} + +static void test_pack_LPINTERNET_CACHE_ENTRY_INFOW(void) +{ + /* LPINTERNET_CACHE_ENTRY_INFOW */ + TEST_TYPE_SIZE (LPINTERNET_CACHE_ENTRY_INFOW, 8) + TEST_TYPE_ALIGN (LPINTERNET_CACHE_ENTRY_INFOW, 8) +} + +static void test_pack_LPINTERNET_CERTIFICATE_INFOA(void) +{ + /* LPINTERNET_CERTIFICATE_INFOA */ + TEST_TYPE_SIZE (LPINTERNET_CERTIFICATE_INFOA, 8) + TEST_TYPE_ALIGN (LPINTERNET_CERTIFICATE_INFOA, 8) + TEST_TARGET_SIZE (LPINTERNET_CERTIFICATE_INFOA, 64) + TEST_TARGET_ALIGN(LPINTERNET_CERTIFICATE_INFOA, 8) +} + +static void test_pack_LPINTERNET_CERTIFICATE_INFOW(void) +{ + /* LPINTERNET_CERTIFICATE_INFOW */ + TEST_TYPE_SIZE (LPINTERNET_CERTIFICATE_INFOW, 8) + TEST_TYPE_ALIGN (LPINTERNET_CERTIFICATE_INFOW, 8) + TEST_TARGET_SIZE (LPINTERNET_CERTIFICATE_INFOW, 64) + TEST_TARGET_ALIGN(LPINTERNET_CERTIFICATE_INFOW, 8) +} + +static void test_pack_LPINTERNET_CONNECTED_INFO(void) +{ + /* LPINTERNET_CONNECTED_INFO */ + TEST_TYPE_SIZE (LPINTERNET_CONNECTED_INFO, 8) + TEST_TYPE_ALIGN (LPINTERNET_CONNECTED_INFO, 8) + TEST_TARGET_SIZE (LPINTERNET_CONNECTED_INFO, 8) + TEST_TARGET_ALIGN(LPINTERNET_CONNECTED_INFO, 4) +} + +static void test_pack_LPINTERNET_PORT(void) +{ + /* LPINTERNET_PORT */ + TEST_TYPE_SIZE (LPINTERNET_PORT, 8) + TEST_TYPE_ALIGN (LPINTERNET_PORT, 8) + TEST_TARGET_SIZE (LPINTERNET_PORT, 2) + TEST_TARGET_ALIGN(LPINTERNET_PORT, 2) +} +static void test_pack_LPINTERNET_PROXY_INFOA(void) +{ + /* LPINTERNET_PROXY_INFOA */ + TEST_TYPE_SIZE (LPINTERNET_PROXY_INFOA, 8) + TEST_TYPE_ALIGN (LPINTERNET_PROXY_INFOA, 8) + TEST_TARGET_SIZE (LPINTERNET_PROXY_INFOA, 24) + TEST_TARGET_ALIGN(LPINTERNET_PROXY_INFOA, 8) +} + +static void test_pack_LPINTERNET_PROXY_INFOW(void) +{ + /* LPINTERNET_PROXY_INFOW */ + TEST_TYPE_SIZE (LPINTERNET_PROXY_INFOW, 8) + TEST_TYPE_ALIGN (LPINTERNET_PROXY_INFOW, 8) + TEST_TARGET_SIZE (LPINTERNET_PROXY_INFOW, 24) + TEST_TARGET_ALIGN(LPINTERNET_PROXY_INFOW, 8) +} + +static void test_pack_LPINTERNET_STATUS_CALLBACK(void) +{ + /* LPINTERNET_STATUS_CALLBACK */ + TEST_TYPE_SIZE (LPINTERNET_STATUS_CALLBACK, 8) + TEST_TYPE_ALIGN (LPINTERNET_STATUS_CALLBACK, 8) + TEST_TARGET_SIZE (LPINTERNET_STATUS_CALLBACK, 8) + TEST_TARGET_ALIGN(LPINTERNET_STATUS_CALLBACK, 8) +} + +static void test_pack_LPINTERNET_VERSION_INFO(void) +{ + /* LPINTERNET_VERSION_INFO */ + TEST_TYPE_SIZE (LPINTERNET_VERSION_INFO, 8) + TEST_TYPE_ALIGN (LPINTERNET_VERSION_INFO, 8) + TEST_TARGET_SIZE (LPINTERNET_VERSION_INFO, 8) + TEST_TARGET_ALIGN(LPINTERNET_VERSION_INFO, 4) +} + +static void test_pack_LPURL_COMPONENTSA(void) +{ + /* LPURL_COMPONENTSA */ + TEST_TYPE_SIZE (LPURL_COMPONENTSA, 8) + TEST_TYPE_ALIGN (LPURL_COMPONENTSA, 8) +} + +static void test_pack_LPURL_COMPONENTSW(void) +{ + /* LPURL_COMPONENTSW */ + TEST_TYPE_SIZE (LPURL_COMPONENTSW, 8) + TEST_TYPE_ALIGN (LPURL_COMPONENTSW, 8) +} + +static void test_pack_PFN_AUTH_NOTIFY(void) +{ + /* PFN_AUTH_NOTIFY */ + TEST_TYPE_SIZE (PFN_AUTH_NOTIFY, 8) + TEST_TYPE_ALIGN (PFN_AUTH_NOTIFY, 8) +} + +static void test_pack_PFN_DIAL_HANDLER(void) +{ + /* PFN_DIAL_HANDLER */ + TEST_TYPE_SIZE (PFN_DIAL_HANDLER, 8) + TEST_TYPE_ALIGN (PFN_DIAL_HANDLER, 8) +} + +static void test_pack_URL_COMPONENTSA(void) +{ + /* URL_COMPONENTSA */ + TEST_FIELD_SIZE (URL_COMPONENTSA, dwStructSize, 4) + TEST_FIELD_ALIGN (URL_COMPONENTSA, dwStructSize, 4) + TEST_FIELD_OFFSET(URL_COMPONENTSA, dwStructSize, 0) + TEST_FIELD_SIZE (URL_COMPONENTSA, lpszScheme, 8) + TEST_FIELD_ALIGN (URL_COMPONENTSA, lpszScheme, 8) + TEST_FIELD_OFFSET(URL_COMPONENTSA, lpszScheme, 8) + TEST_FIELD_SIZE (URL_COMPONENTSA, dwSchemeLength, 4) + TEST_FIELD_ALIGN (URL_COMPONENTSA, dwSchemeLength, 4) + TEST_FIELD_OFFSET(URL_COMPONENTSA, dwSchemeLength, 16) +} + +static void test_pack_URL_COMPONENTSW(void) +{ + /* URL_COMPONENTSW */ + TEST_FIELD_SIZE (URL_COMPONENTSW, dwStructSize, 4) + TEST_FIELD_ALIGN (URL_COMPONENTSW, dwStructSize, 4) + TEST_FIELD_OFFSET(URL_COMPONENTSW, dwStructSize, 0) + TEST_FIELD_SIZE (URL_COMPONENTSW, lpszScheme, 8) + TEST_FIELD_ALIGN (URL_COMPONENTSW, lpszScheme, 8) + TEST_FIELD_OFFSET(URL_COMPONENTSW, lpszScheme, 8) + TEST_FIELD_SIZE (URL_COMPONENTSW, dwSchemeLength, 4) + TEST_FIELD_ALIGN (URL_COMPONENTSW, dwSchemeLength, 4) + TEST_FIELD_OFFSET(URL_COMPONENTSW, dwSchemeLength, 16) +} + +#else /* _WIN64 */ static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEA(void) { - /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 8) TEST_TYPE_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEA, ShortAbstract, 4) @@ -106,7 +1333,7 @@ static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEW(void) { - /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_ABSTRACT_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 8) TEST_TYPE_ALIGN (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_ABSTRACT_ATTRIBUTE_TYPEW, ShortAbstract, 4) @@ -119,7 +1346,7 @@ static void test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEA(void) { - /* GOPHER_ADMIN_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_ADMIN_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEA, 8) TEST_TYPE_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEA, Comment, 4) @@ -132,7 +1359,7 @@ static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEW(void) { - /* GOPHER_ADMIN_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_ADMIN_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEW, 8) TEST_TYPE_ALIGN (GOPHER_ADMIN_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_ADMIN_ATTRIBUTE_TYPEW, Comment, 4) @@ -145,7 +1372,7 @@ static void test_pack_GOPHER_ADMIN_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_ASK_ATTRIBUTE_TYPEA(void) { - /* GOPHER_ASK_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_ASK_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEA, 8) TEST_TYPE_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEA, QuestionType, 4) @@ -158,7 +1385,7 @@ static void test_pack_GOPHER_ASK_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_ASK_ATTRIBUTE_TYPEW(void) { - /* GOPHER_ASK_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_ASK_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEW, 8) TEST_TYPE_ALIGN (GOPHER_ASK_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_ASK_ATTRIBUTE_TYPEW, QuestionType, 4) @@ -185,7 +1412,7 @@ static void test_pack_GOPHER_ATTRIBUTE_ENUMERATORW(void) static void test_pack_GOPHER_ATTRIBUTE_TYPEA(void) { - /* GOPHER_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_ATTRIBUTE_TYPEA */ TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEA, CategoryId, 4) TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEA, CategoryId, 4) TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEA, CategoryId, 0) @@ -196,7 +1423,7 @@ static void test_pack_GOPHER_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_ATTRIBUTE_TYPEW(void) { - /* GOPHER_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_ATTRIBUTE_TYPEW */ TEST_FIELD_SIZE (GOPHER_ATTRIBUTE_TYPEW, CategoryId, 4) TEST_FIELD_ALIGN (GOPHER_ATTRIBUTE_TYPEW, CategoryId, 4) TEST_FIELD_OFFSET(GOPHER_ATTRIBUTE_TYPEW, CategoryId, 0) @@ -207,7 +1434,7 @@ static void test_pack_GOPHER_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_FIND_DATAA(void) { - /* GOPHER_FIND_DATAA (pack 4) */ + /* GOPHER_FIND_DATAA */ TEST_TYPE_SIZE (GOPHER_FIND_DATAA, 808) TEST_TYPE_ALIGN (GOPHER_FIND_DATAA, 4) TEST_FIELD_SIZE (GOPHER_FIND_DATAA, DisplayString, 129) @@ -232,7 +1459,7 @@ static void test_pack_GOPHER_FIND_DATAA(void) static void test_pack_GOPHER_FIND_DATAW(void) { - /* GOPHER_FIND_DATAW (pack 4) */ + /* GOPHER_FIND_DATAW */ TEST_TYPE_SIZE (GOPHER_FIND_DATAW, 1588) TEST_TYPE_ALIGN (GOPHER_FIND_DATAW, 4) TEST_FIELD_SIZE (GOPHER_FIND_DATAW, DisplayString, 258) @@ -257,7 +1484,7 @@ static void test_pack_GOPHER_FIND_DATAW(void) static void test_pack_GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE(void) { - /* GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 24) TEST_TYPE_ALIGN (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE, DegreesNorth, 4) @@ -282,7 +1509,7 @@ static void test_pack_GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEA(void) { - /* GOPHER_LOCATION_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_LOCATION_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEA, Location, 4) @@ -292,7 +1519,7 @@ static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEW(void) { - /* GOPHER_LOCATION_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_LOCATION_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_LOCATION_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_LOCATION_ATTRIBUTE_TYPEW, Location, 4) @@ -302,7 +1529,7 @@ static void test_pack_GOPHER_LOCATION_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_MOD_DATE_ATTRIBUTE_TYPE(void) { - /* GOPHER_MOD_DATE_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_MOD_DATE_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, 8) TEST_TYPE_ALIGN (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_MOD_DATE_ATTRIBUTE_TYPE, DateAndTime, 8) @@ -312,7 +1539,7 @@ static void test_pack_GOPHER_MOD_DATE_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA(void) { - /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA, Organization, 4) @@ -322,7 +1549,7 @@ static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW(void) { - /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW, Organization, 4) @@ -332,7 +1559,7 @@ static void test_pack_GOPHER_ORGANIZATION_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEA(void) { - /* GOPHER_PROVIDER_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_PROVIDER_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEA, Provider, 4) @@ -342,7 +1569,7 @@ static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEW(void) { - /* GOPHER_PROVIDER_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_PROVIDER_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_PROVIDER_ATTRIBUTE_TYPEW, Provider, 4) @@ -352,7 +1579,7 @@ static void test_pack_GOPHER_PROVIDER_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_SCORE_ATTRIBUTE_TYPE(void) { - /* GOPHER_SCORE_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_SCORE_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_SCORE_ATTRIBUTE_TYPE, 4) TEST_TYPE_ALIGN (GOPHER_SCORE_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_SCORE_ATTRIBUTE_TYPE, Score, 4) @@ -362,7 +1589,7 @@ static void test_pack_GOPHER_SCORE_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE(void) { - /* GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 8) TEST_TYPE_ALIGN (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE, LowerBound, 4) @@ -375,7 +1602,7 @@ static void test_pack_GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEA(void) { - /* GOPHER_SITE_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_SITE_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEA, Site, 4) @@ -385,7 +1612,7 @@ static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEW(void) { - /* GOPHER_SITE_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_SITE_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_SITE_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_SITE_ATTRIBUTE_TYPEW, Site, 4) @@ -395,7 +1622,7 @@ static void test_pack_GOPHER_SITE_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_TIMEZONE_ATTRIBUTE_TYPE(void) { - /* GOPHER_TIMEZONE_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_TIMEZONE_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) TEST_TYPE_ALIGN (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_TIMEZONE_ATTRIBUTE_TYPE, Zone, 4) @@ -405,7 +1632,7 @@ static void test_pack_GOPHER_TIMEZONE_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_TTL_ATTRIBUTE_TYPE(void) { - /* GOPHER_TTL_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_TTL_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_TTL_ATTRIBUTE_TYPE, 4) TEST_TYPE_ALIGN (GOPHER_TTL_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_TTL_ATTRIBUTE_TYPE, Ttl, 4) @@ -415,7 +1642,7 @@ static void test_pack_GOPHER_TTL_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEA(void) { - /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEA, Text, 4) @@ -425,7 +1652,7 @@ static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEW(void) { - /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_UNKNOWN_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_UNKNOWN_ATTRIBUTE_TYPEW, Text, 4) @@ -435,7 +1662,7 @@ static void test_pack_GOPHER_UNKNOWN_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_VERONICA_ATTRIBUTE_TYPE(void) { - /* GOPHER_VERONICA_ATTRIBUTE_TYPE (pack 4) */ + /* GOPHER_VERONICA_ATTRIBUTE_TYPE */ TEST_TYPE_SIZE (GOPHER_VERONICA_ATTRIBUTE_TYPE, 4) TEST_TYPE_ALIGN (GOPHER_VERONICA_ATTRIBUTE_TYPE, 4) TEST_FIELD_SIZE (GOPHER_VERONICA_ATTRIBUTE_TYPE, TreeWalk, 4) @@ -445,7 +1672,7 @@ static void test_pack_GOPHER_VERONICA_ATTRIBUTE_TYPE(void) static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEA(void) { - /* GOPHER_VERSION_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_VERSION_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEA, 4) TEST_TYPE_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEA, Version, 4) @@ -455,7 +1682,7 @@ static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEW(void) { - /* GOPHER_VERSION_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_VERSION_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEW, 4) TEST_TYPE_ALIGN (GOPHER_VERSION_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_VERSION_ATTRIBUTE_TYPEW, Version, 4) @@ -465,7 +1692,7 @@ static void test_pack_GOPHER_VERSION_ATTRIBUTE_TYPEW(void) static void test_pack_GOPHER_VIEW_ATTRIBUTE_TYPEA(void) { - /* GOPHER_VIEW_ATTRIBUTE_TYPEA (pack 4) */ + /* GOPHER_VIEW_ATTRIBUTE_TYPEA */ TEST_TYPE_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, 12) TEST_TYPE_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEA, 4) TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEA, ContentType, 4) @@ -481,7 +1708,7 @@ static void test_pack_GOPHER_VIEW_ATTRIBUTE_TYPEA(void) static void test_pack_GOPHER_VIEW_ATTRIBUTE_TYPEW(void) { - /* GOPHER_VIEW_ATTRIBUTE_TYPEW (pack 4) */ + /* GOPHER_VIEW_ATTRIBUTE_TYPEW */ TEST_TYPE_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, 12) TEST_TYPE_ALIGN (GOPHER_VIEW_ATTRIBUTE_TYPEW, 4) TEST_FIELD_SIZE (GOPHER_VIEW_ATTRIBUTE_TYPEW, ContentType, 4) @@ -512,7 +1739,7 @@ static void test_pack_HINTERNET(void) static void test_pack_HTTP_VERSION_INFO(void) { - /* HTTP_VERSION_INFO (pack 4) */ + /* HTTP_VERSION_INFO */ TEST_TYPE_SIZE (HTTP_VERSION_INFO, 8) TEST_TYPE_ALIGN (HTTP_VERSION_INFO, 4) TEST_FIELD_SIZE (HTTP_VERSION_INFO, dwMajorVersion, 4) @@ -525,7 +1752,7 @@ static void test_pack_HTTP_VERSION_INFO(void) static void test_pack_INTERNET_ASYNC_RESULT(void) { - /* INTERNET_ASYNC_RESULT (pack 4) */ + /* INTERNET_ASYNC_RESULT */ TEST_TYPE_SIZE (INTERNET_ASYNC_RESULT, 8) TEST_TYPE_ALIGN (INTERNET_ASYNC_RESULT, 4) TEST_FIELD_SIZE (INTERNET_ASYNC_RESULT, dwResult, 4) @@ -538,7 +1765,7 @@ static void test_pack_INTERNET_ASYNC_RESULT(void) static void test_pack_INTERNET_AUTH_NOTIFY_DATA(void) { - /* INTERNET_AUTH_NOTIFY_DATA (pack 4) */ + /* INTERNET_AUTH_NOTIFY_DATA */ TEST_TYPE_SIZE (INTERNET_AUTH_NOTIFY_DATA, 16) TEST_TYPE_ALIGN (INTERNET_AUTH_NOTIFY_DATA, 4) TEST_FIELD_SIZE (INTERNET_AUTH_NOTIFY_DATA, cbStruct, 4) @@ -557,7 +1784,7 @@ static void test_pack_INTERNET_AUTH_NOTIFY_DATA(void) static void test_pack_INTERNET_BUFFERSA(void) { - /* INTERNET_BUFFERSA (pack 4) */ + /* INTERNET_BUFFERSA */ TEST_TYPE_SIZE (INTERNET_BUFFERSA, 40) TEST_TYPE_ALIGN (INTERNET_BUFFERSA, 4) TEST_FIELD_SIZE (INTERNET_BUFFERSA, dwStructSize, 4) @@ -594,7 +1821,7 @@ static void test_pack_INTERNET_BUFFERSA(void) static void test_pack_INTERNET_BUFFERSW(void) { - /* INTERNET_BUFFERSW (pack 4) */ + /* INTERNET_BUFFERSW */ TEST_TYPE_SIZE (INTERNET_BUFFERSW, 40) TEST_TYPE_ALIGN (INTERNET_BUFFERSW, 4) TEST_FIELD_SIZE (INTERNET_BUFFERSW, dwStructSize, 4) @@ -631,7 +1858,7 @@ static void test_pack_INTERNET_BUFFERSW(void) static void test_pack_INTERNET_CACHE_ENTRY_INFOA(void) { - /* INTERNET_CACHE_ENTRY_INFOA (pack 4) */ + /* INTERNET_CACHE_ENTRY_INFOA */ TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 4) TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 4) TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOA, dwStructSize, 0) @@ -681,7 +1908,7 @@ static void test_pack_INTERNET_CACHE_ENTRY_INFOA(void) static void test_pack_INTERNET_CACHE_ENTRY_INFOW(void) { - /* INTERNET_CACHE_ENTRY_INFOW (pack 4) */ + /* INTERNET_CACHE_ENTRY_INFOW */ TEST_FIELD_SIZE (INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 4) TEST_FIELD_ALIGN (INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 4) TEST_FIELD_OFFSET(INTERNET_CACHE_ENTRY_INFOW, dwStructSize, 0) @@ -731,7 +1958,7 @@ static void test_pack_INTERNET_CACHE_ENTRY_INFOW(void) static void test_pack_INTERNET_CERTIFICATE_INFOA(void) { - /* INTERNET_CERTIFICATE_INFOA (pack 4) */ + /* INTERNET_CERTIFICATE_INFOA */ TEST_TYPE_SIZE (INTERNET_CERTIFICATE_INFOA, 40) TEST_TYPE_ALIGN (INTERNET_CERTIFICATE_INFOA, 4) TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOA, ftExpiry, 8) @@ -762,7 +1989,7 @@ static void test_pack_INTERNET_CERTIFICATE_INFOA(void) static void test_pack_INTERNET_CERTIFICATE_INFOW(void) { - /* INTERNET_CERTIFICATE_INFOW (pack 4) */ + /* INTERNET_CERTIFICATE_INFOW */ TEST_TYPE_SIZE (INTERNET_CERTIFICATE_INFOW, 40) TEST_TYPE_ALIGN (INTERNET_CERTIFICATE_INFOW, 4) TEST_FIELD_SIZE (INTERNET_CERTIFICATE_INFOW, ftExpiry, 8) @@ -793,7 +2020,7 @@ static void test_pack_INTERNET_CERTIFICATE_INFOW(void) static void test_pack_INTERNET_CONNECTED_INFO(void) { - /* INTERNET_CONNECTED_INFO (pack 4) */ + /* INTERNET_CONNECTED_INFO */ TEST_TYPE_SIZE (INTERNET_CONNECTED_INFO, 8) TEST_TYPE_ALIGN (INTERNET_CONNECTED_INFO, 4) TEST_FIELD_SIZE (INTERNET_CONNECTED_INFO, dwConnectedState, 4) @@ -814,7 +2041,7 @@ static void test_pack_INTERNET_PORT(void) static void test_pack_INTERNET_PROXY_INFOA(void) { - /* INTERNET_PROXY_INFOA (pack 4) */ + /* INTERNET_PROXY_INFOA */ TEST_TYPE_SIZE (INTERNET_PROXY_INFOA, 12) TEST_TYPE_ALIGN (INTERNET_PROXY_INFOA, 4) TEST_FIELD_SIZE (INTERNET_PROXY_INFOA, dwAccessType, 4) @@ -830,7 +2057,7 @@ static void test_pack_INTERNET_PROXY_INFOA(void) static void test_pack_INTERNET_PROXY_INFOW(void) { - /* INTERNET_PROXY_INFOW (pack 4) */ + /* INTERNET_PROXY_INFOW */ TEST_TYPE_SIZE (INTERNET_PROXY_INFOW, 12) TEST_TYPE_ALIGN (INTERNET_PROXY_INFOW, 4) TEST_FIELD_SIZE (INTERNET_PROXY_INFOW, dwAccessType, 4) @@ -853,7 +2080,7 @@ static void test_pack_INTERNET_STATUS_CALLBACK(void) static void test_pack_INTERNET_VERSION_INFO(void) { - /* INTERNET_VERSION_INFO (pack 4) */ + /* INTERNET_VERSION_INFO */ TEST_TYPE_SIZE (INTERNET_VERSION_INFO, 8) TEST_TYPE_ALIGN (INTERNET_VERSION_INFO, 4) TEST_FIELD_SIZE (INTERNET_VERSION_INFO, dwMajorVersion, 4) @@ -1300,7 +2527,7 @@ static void test_pack_PFN_DIAL_HANDLER(void) static void test_pack_URL_COMPONENTSA(void) { - /* URL_COMPONENTSA (pack 4) */ + /* URL_COMPONENTSA */ TEST_FIELD_SIZE (URL_COMPONENTSA, dwStructSize, 4) TEST_FIELD_ALIGN (URL_COMPONENTSA, dwStructSize, 4) TEST_FIELD_OFFSET(URL_COMPONENTSA, dwStructSize, 0) @@ -1314,7 +2541,7 @@ static void test_pack_URL_COMPONENTSA(void) static void test_pack_URL_COMPONENTSW(void) { - /* URL_COMPONENTSW (pack 4) */ + /* URL_COMPONENTSW */ TEST_FIELD_SIZE (URL_COMPONENTSW, dwStructSize, 4) TEST_FIELD_ALIGN (URL_COMPONENTSW, dwStructSize, 4) TEST_FIELD_OFFSET(URL_COMPONENTSW, dwStructSize, 0) @@ -1326,6 +2553,8 @@ static void test_pack_URL_COMPONENTSW(void) TEST_FIELD_OFFSET(URL_COMPONENTSW, dwSchemeLength, 8) } +#endif /* _WIN64 */ + static void test_pack(void) { test_pack_GOPHER_ABSTRACT_ATTRIBUTE_TYPEA(); @@ -1434,9 +2663,5 @@ static void test_pack(void) START_TEST(generated) { -#ifdef _WIN64 - ok(0, "The type size / alignment tests don't support Win64 yet\n"); -#else test_pack(); -#endif } diff --git a/rostests/winetests/wininet/http.c b/rostests/winetests/wininet/http.c index e3c33bd8748..0faeb54dc8a 100644 --- a/rostests/winetests/wininet/http.c +++ b/rostests/winetests/wininet/http.c @@ -105,6 +105,35 @@ static CHAR status_string[MAX_INTERNET_STATUS][MAX_STATUS_NAME]; static HANDLE hCompleteEvent; +#define TESTF_REDIRECT 0x01 +#define TESTF_COMPRESSED 0x02 +#define TESTF_ALLOW_COOKIE 0x04 + +typedef struct { + const char *url; + const char *redirected_url; + const char *host; + const char *path; + DWORD flags; +} test_data_t; + +static const test_data_t test_data[] = { + { + "http://test.winehq.org/testredirect", + "http://test.winehq.org/hello.html", + "test.winehq.org", + "/testredirect", + TESTF_REDIRECT + }, + { + "http://www.codeweavers.com/", + "http://www.codeweavers.com/", + "www.codeweavers.com", + "", + TESTF_COMPRESSED|TESTF_ALLOW_COOKIE + } +}; + static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET ,INTERNET_STATUS_CALLBACK); @@ -239,7 +268,7 @@ static VOID WINAPI callback( } } -static void InternetReadFile_test(int flags) +static void InternetReadFile_test(int flags, const test_data_t *test) { BOOL res; CHAR buffer[4000]; @@ -250,10 +279,11 @@ static void InternetReadFile_test(int flags) hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - trace("Starting InternetReadFile test with flags 0x%x\n",flags); + trace("Starting InternetReadFile test with flags 0x%x on url %s\n",flags,test->url); trace("InternetOpenA <--\n"); - hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags); + hi = InternetOpenA((test->flags & TESTF_COMPRESSED) ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" : "", + INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags); ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError()); trace("InternetOpenA -->\n"); @@ -264,7 +294,7 @@ static void InternetReadFile_test(int flags) SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED); trace("InternetConnectA <--\n"); - hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, + hic=InternetConnectA(hi, test->host, INTERNET_INVALID_PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef); ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError()); trace("InternetConnectA -->\n"); @@ -275,7 +305,7 @@ static void InternetReadFile_test(int flags) SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED); trace("HttpOpenRequestA <--\n"); - hor = HttpOpenRequestA(hic, "GET", "/testredirect", NULL, NULL, types, + hor = HttpOpenRequestA(hic, "GET", test->path, NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead); if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) { @@ -295,7 +325,7 @@ static void InternetReadFile_test(int flags) length = sizeof(buffer); res = InternetQueryOptionA(hor, INTERNET_OPTION_URL, buffer, &length); ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError()); - ok(!strcmp(buffer, "http://test.winehq.org/testredirect"), "Wrong URL %s\n", buffer); + ok(!strcmp(buffer, test->url), "Wrong URL %s, expected %s\n", buffer, test->url); length = sizeof(buffer); res = HttpQueryInfoA(hor, HTTP_QUERY_RAW_HEADERS, buffer, &length, 0x0); @@ -306,6 +336,10 @@ static void InternetReadFile_test(int flags) CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED); CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME); CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED); + if(test->flags & TESTF_ALLOW_COOKIE) { + SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT); + SET_OPTIONAL(INTERNET_STATUS_COOKIE_RECEIVED); + } if (first_connection_to_test_url) { SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME); @@ -322,12 +356,14 @@ static void InternetReadFile_test(int flags) SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER); SET_WINE_ALLOW(INTERNET_STATUS_CONNECTED_TO_SERVER); SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER); - SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, 2); - SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, 2); - SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, 2); - SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, 2); - SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2); - SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2); + SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1); + SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1); + SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1); + SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1); + if(test->flags & TESTF_REDIRECT) { + SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2); + SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2); + } SET_EXPECT(INTERNET_STATUS_REDIRECT); SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); @@ -336,9 +372,19 @@ static void InternetReadFile_test(int flags) else SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE); + if(test->flags & TESTF_COMPRESSED) { + BOOL b = TRUE; + + res = InternetSetOption(hor, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b)); + ok(res || broken(!res && GetLastError() == ERROR_INTERNET_INVALID_OPTION), + "InternetSetOption failed: %u\n", GetLastError()); + if(!res) + goto abort; + } + trace("HttpSendRequestA -->\n"); SetLastError(0xdeadbeef); - res = HttpSendRequestA(hor, "", -1, NULL, 0); + res = HttpSendRequestA(hor, (test->flags & TESTF_COMPRESSED) ? "Accept-Encoding: gzip, deflate" : "", -1, NULL, 0); if (flags & INTERNET_FLAG_ASYNC) ok(!res && (GetLastError() == ERROR_IO_PENDING), "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n"); @@ -350,6 +396,10 @@ static void InternetReadFile_test(int flags) if (flags & INTERNET_FLAG_ASYNC) WaitForSingleObject(hCompleteEvent, INFINITE); + if(test->flags & TESTF_ALLOW_COOKIE) { + CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT); + CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_RECEIVED); + } if (first_connection_to_test_url) { CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME); @@ -360,11 +410,12 @@ static void InternetReadFile_test(int flags) CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME); CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED); } - CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, 2); - CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, 2); - CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, 2); - CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, 2); - CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT); + CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1); + CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1); + CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1); + CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1); + if(test->flags & TESTF_REDIRECT) + CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT); if (flags & INTERNET_FLAG_ASYNC) CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE); else @@ -389,16 +440,24 @@ static void InternetReadFile_test(int flags) length = sizeof(buffer); res = InternetQueryOptionA(hor, INTERNET_OPTION_URL, buffer, &length); ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError()); - ok(!strcmp(buffer, "http://test.winehq.org/hello.html"), "Wrong URL %s\n", buffer); + ok(!strcmp(buffer, test->redirected_url), "Wrong URL %s\n", buffer); length = 16; res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0); - trace("Option 0x5 -> %i %s (%u)\n",res,buffer,GetLastError()); + trace("Option HTTP_QUERY_CONTENT_LENGTH -> %i %s (%u)\n",res,buffer,GetLastError()); + if(test->flags & TESTF_COMPRESSED) + ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, + "expected ERROR_HTTP_HEADER_NOT_FOUND, got %x (%u)\n", res, GetLastError()); length = 100; res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0); buffer[length]=0; - trace("Option 0x1 -> %i %s\n",res,buffer); + trace("Option HTTP_QUERY_CONTENT_TYPE -> %i %s\n",res,buffer); + + length = 100; + res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_ENCODING,buffer,&length,0x0); + buffer[length]=0; + trace("Option HTTP_QUERY_CONTENT_ENCODING -> %i %s\n",res,buffer); SetLastError(0xdeadbeef); res = InternetReadFile(NULL, buffer, 100, &length); @@ -447,8 +506,10 @@ static void InternetReadFile_test(int flags) if (length == 0) break; } - CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2); - CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2); + if(test->flags & TESTF_REDIRECT) { + CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2); + CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2); + } abort: trace("aborting\n"); SET_EXPECT2(INTERNET_STATUS_HANDLE_CLOSING, (hor != 0x0) + (hic != 0x0)); @@ -493,6 +554,114 @@ abort: first_connection_to_test_url = FALSE; } +static void InternetReadFile_chunked_test(void) +{ + BOOL res; + CHAR buffer[4000]; + DWORD length; + const char *types[2] = { "*", NULL }; + HINTERNET hi, hic = 0, hor = 0; + + trace("Starting InternetReadFile chunked test\n"); + + trace("InternetOpenA <--\n"); + hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError()); + trace("InternetOpenA -->\n"); + + if (hi == 0x0) goto abort; + + trace("InternetConnectA <--\n"); + hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, + NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef); + ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError()); + trace("InternetConnectA -->\n"); + + if (hic == 0x0) goto abort; + + trace("HttpOpenRequestA <--\n"); + hor = HttpOpenRequestA(hic, "GET", "/testchunked", NULL, NULL, types, + INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, + 0xdeadbead); + if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) { + /* + * If the internet name can't be resolved we are probably behind + * a firewall or in some other way not directly connected to the + * Internet. Not enough reason to fail the test. Just ignore and + * abort. + */ + } else { + ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError()); + } + trace("HttpOpenRequestA -->\n"); + + if (hor == 0x0) goto abort; + + trace("HttpSendRequestA -->\n"); + SetLastError(0xdeadbeef); + res = HttpSendRequestA(hor, "", -1, NULL, 0); + ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED), + "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError()); + trace("HttpSendRequestA <--\n"); + + length = 100; + res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0); + buffer[length]=0; + trace("Option CONTENT_TYPE -> %i %s\n",res,buffer); + + SetLastError( 0xdeadbeef ); + length = 100; + res = HttpQueryInfoA(hor,HTTP_QUERY_TRANSFER_ENCODING,buffer,&length,0x0); + buffer[length]=0; + trace("Option TRANSFER_ENCODING -> %i %s\n",res,buffer); + ok( res, "Failed to get TRANSFER_ENCODING option, error %u\n", GetLastError() ); + ok( !strcmp( buffer, "chunked" ), "Wrong transfer encoding '%s'\n", buffer ); + + SetLastError( 0xdeadbeef ); + length = 16; + res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0); + ok( !res, "Found CONTENT_LENGTH option '%s'\n", buffer ); + ok( GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "Wrong error %u\n", GetLastError() ); + + length = 100; + trace("Entering Query loop\n"); + + while (TRUE) + { + res = InternetQueryDataAvailable(hor,&length,0x0,0x0); + ok(!(!res && length != 0),"InternetQueryDataAvailable failed with non-zero length\n"); + ok(res, "InternetQueryDataAvailable failed, error %d\n", GetLastError()); + trace("got %u available\n",length); + if (length) + { + DWORD got; + char *buffer = HeapAlloc(GetProcessHeap(),0,length+1); + + res = InternetReadFile(hor,buffer,length,&got); + + buffer[got]=0; + trace("ReadFile -> %i %i\n",res,got); + ok( length == got, "only got %u of %u available\n", got, length ); + ok( buffer[got-1] == '\n', "received partial line '%s'\n", buffer ); + + HeapFree(GetProcessHeap(),0,buffer); + if (!got) break; + } + if (length == 0) + break; + } +abort: + trace("aborting\n"); + if (hor != 0x0) { + res = InternetCloseHandle(hor); + ok (res, "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n"); + } + if (hi != 0x0) { + res = InternetCloseHandle(hi); + ok (res, "InternetCloseHandle of handle opened by InternetOpenA failed\n"); + } +} + static void InternetReadFileExA_test(int flags) { DWORD rc; @@ -802,8 +971,7 @@ static void HttpSendRequestEx_test(void) HINTERNET hRequest; INTERNET_BUFFERS BufferIn; - DWORD dwBytesWritten; - DWORD dwBytesRead; + DWORD dwBytesWritten, dwBytesRead, error; CHAR szBuffer[256]; int i; BOOL ret; @@ -839,8 +1007,11 @@ static void HttpSendRequestEx_test(void) BufferIn.dwOffsetLow = 0; BufferIn.dwOffsetHigh = 0; + SetLastError(0xdeadbeef); ret = HttpSendRequestEx(hRequest, &BufferIn, NULL, 0 ,0); - ok(ret, "HttpSendRequestEx Failed with error %u\n", GetLastError()); + error = GetLastError(); + ok(ret, "HttpSendRequestEx Failed with error %u\n", error); + ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", error); for (i = 3; szPostData[i]; i++) ok(InternetWriteFile(hRequest, &szPostData[i], 1, &dwBytesWritten), @@ -942,7 +1113,7 @@ static void test_http_cache(void) size = sizeof(url); ret = InternetQueryOptionA(request, INTERNET_OPTION_URL, url, &size); - ok(ret, "InternetQueryOptionA(INTERNET_OPTION_url) failed: %u\n", GetLastError()); + ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError()); ok(!strcmp(url, "http://test.winehq.org/hello.html"), "Wrong URL %s\n", url); size = sizeof(file_name); @@ -977,7 +1148,7 @@ static void test_http_cache(void) file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - todo_wine ok(file != INVALID_HANDLE_VALUE, "CreateFile succeeded\n"); + ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError()); CloseHandle(file); request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0); @@ -993,13 +1164,20 @@ static void test_http_cache(void) ok(ret, "HttpSendRequest failed: %u\n", GetLastError()); size = sizeof(file_name); + file_name[0] = 0; ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size); - todo_wine ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed %u\n", GetLastError()); - - file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + if (ret) + { + file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - todo_wine ok(file != INVALID_HANDLE_VALUE, "CreateFile succeeded\n"); - CloseHandle(file); + ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError()); + CloseHandle(file); + } + else + { + /* < IE8 */ + ok(file_name[0] == 0, "Didn't expect a file name\n"); + } ok(InternetCloseHandle(request), "Close request handle failed\n"); ok(InternetCloseHandle(connect), "Close connect handle failed\n"); @@ -1284,15 +1462,47 @@ static void HttpHeaders_test(void) ok(index == 1, "Index was not incremented\n"); ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer); + /* Ensure that malformed header separators are ignored and don't cause a failure */ + ok(HttpAddRequestHeaders(hRequest,"\r\rMalformedTest:value\n\nMalformedTestTwo: value2\rMalformedTestThree: value3\n\n\r\r\n",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE), + "Failed to add header with malformed entries in list\n"); + + index = 0; + len = sizeof(buffer); + strcpy(buffer,"MalformedTest"); + 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); + index = 0; + len = sizeof(buffer); + strcpy(buffer,"MalformedTestTwo"); + 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,"value2")==0, "incorrect string was returned(%s)\n",buffer); + index = 0; + len = sizeof(buffer); + strcpy(buffer,"MalformedTestThree"); + 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,"value3")==0, "incorrect string was returned(%s)\n",buffer); + ok(InternetCloseHandle(hRequest), "Close request handle failed\n"); done: ok(InternetCloseHandle(hConnect), "Close connect handle failed\n"); ok(InternetCloseHandle(hSession), "Close session handle failed\n"); } +static const char garbagemsg[] = +"Garbage: Header\r\n"; + static const char contmsg[] = "HTTP/1.1 100 Continue\r\n"; +static const char expandcontmsg[] = +"HTTP/1.1 100 Continue\r\n" +"Server: winecontinue\r\n" +"Tag: something witty\r\n" +"\r\n"; + static const char okmsg[] = "HTTP/1.1 200 OK\r\n" "Server: winetest\r\n" @@ -1518,6 +1728,19 @@ static DWORD CALLBACK server_thread(LPVOID param) send(c, page1, sizeof page1-1, 0); last_request = 1; } + if (strstr(buffer, "GET /testF")) + { + send(c, expandcontmsg, sizeof expandcontmsg-1, 0); + send(c, garbagemsg, sizeof garbagemsg-1, 0); + send(c, contmsg, sizeof contmsg-1, 0); + send(c, garbagemsg, sizeof garbagemsg-1, 0); + send(c, okmsg, sizeof okmsg-1, 0); + send(c, page1, sizeof page1-1, 0); + } + if (strstr(buffer, "GET /testG")) + { + send(c, page1, sizeof page1-1, 0); + } shutdown(c, 2); closesocket(c); @@ -1558,6 +1781,32 @@ static void test_basic_request(int port, const char *verb, const char *url) InternetCloseHandle(hi); } +static void test_last_error(int port) +{ + HINTERNET hi, hc, hr; + DWORD error; + BOOL r; + + hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(hi != NULL, "open failed\n"); + + hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(hc != NULL, "connect failed\n"); + + hr = HttpOpenRequest(hc, NULL, "/test1", NULL, NULL, NULL, 0, 0); + ok(hr != NULL, "HttpOpenRequest failed\n"); + + SetLastError(0xdeadbeef); + r = HttpSendRequest(hr, NULL, 0, NULL, 0); + error = GetLastError(); + ok(r, "HttpSendRequest failed\n"); + ok(error == ERROR_SUCCESS || broken(error != ERROR_SUCCESS), "expected ERROR_SUCCESS, got %u\n", error); + + InternetCloseHandle(hr); + InternetCloseHandle(hc); + InternetCloseHandle(hi); +} + static void test_proxy_indirect(int port) { HINTERNET hi, hc, hr; @@ -1578,7 +1827,12 @@ static void test_proxy_indirect(int port) sz = sizeof buffer; r = HttpQueryInfo(hr, HTTP_QUERY_PROXY_AUTHENTICATE, buffer, &sz, NULL); - ok(r, "HttpQueryInfo failed\n"); + ok(r || GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo failed: %d\n", GetLastError()); + if (!r) + { + skip("missing proxy header, not testing remaining proxy headers\n"); + goto out; + } ok(!strcmp(buffer, "Basic realm=\"placebo\""), "proxy auth info wrong\n"); sz = sizeof buffer; @@ -1611,6 +1865,7 @@ static void test_proxy_indirect(int port) ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo should fail\n"); ok(r == FALSE, "HttpQueryInfo failed\n"); +out: InternetCloseHandle(hr); InternetCloseHandle(hc); InternetCloseHandle(hi); @@ -1829,7 +2084,6 @@ static void test_http1_1(int port) ok(req != NULL, "HttpOpenRequest failed\n"); ret = HttpSendRequest(req, NULL, 0, NULL, 0); - todo_wine ok(ret, "HttpSendRequest failed\n"); } @@ -1995,6 +2249,69 @@ static void test_invalid_response_headers(int port) InternetCloseHandle(session); } +static void test_response_without_headers(int port) +{ + HINTERNET hi, hc, hr; + DWORD r, count, size, status; + char buffer[1024]; + + SetLastError(0xdeadbeef); + hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(hi != NULL, "open failed %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(hc != NULL, "connect failed %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + hr = HttpOpenRequest(hc, NULL, "/testG", NULL, NULL, NULL, 0, 0); + ok(hr != NULL, "HttpOpenRequest failed %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + r = HttpSendRequest(hr, NULL, 0, NULL, 0); + ok(r, "HttpSendRequest failed %u\n", GetLastError()); + + count = 0; + memset(buffer, 0, sizeof buffer); + SetLastError(0xdeadbeef); + r = InternetReadFile(hr, buffer, sizeof buffer, &count); + ok(r, "InternetReadFile failed %u\n", GetLastError()); + todo_wine ok(count == sizeof page1 - 1, "count was wrong\n"); + todo_wine ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n"); + + status = 0; + size = sizeof(status); + SetLastError(0xdeadbeef); + r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL ); + todo_wine ok(r, "HttpQueryInfo failed %u\n", GetLastError()); + todo_wine ok(status == 200, "expected status 200 got %u\n", status); + + buffer[0] = 0; + size = sizeof(buffer); + SetLastError(0xdeadbeef); + r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_TEXT, buffer, &size, NULL ); + ok(r, "HttpQueryInfo failed %u\n", GetLastError()); + ok(!strcmp(buffer, "OK"), "expected OK got: \"%s\"\n", buffer); + + buffer[0] = 0; + size = sizeof(buffer); + SetLastError(0xdeadbeef); + r = HttpQueryInfo(hr, HTTP_QUERY_VERSION, buffer, &size, NULL); + ok(r, "HttpQueryInfo failed %u\n", GetLastError()); + ok(!strcmp(buffer, "HTTP/1.0"), "expected HTTP/1.0 got: \"%s\"\n", buffer); + + buffer[0] = 0; + size = sizeof(buffer); + SetLastError(0xdeadbeef); + r = HttpQueryInfo(hr, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL); + ok(r, "HttpQueryInfo failed %u\n", GetLastError()); + ok(!strcmp(buffer, "HTTP/1.0 200 OK"), "raw headers wrong: \"%s\"\n", buffer); + + InternetCloseHandle(hr); + InternetCloseHandle(hc); + InternetCloseHandle(hi); +} + static void test_HttpQueryInfo(int port) { HINTERNET hi, hc, hr; @@ -2124,13 +2441,16 @@ static void test_http_connection(void) test_basic_request(si.port, "RPC_IN_DATA", "/test5"); test_basic_request(si.port, "RPC_OUT_DATA", "/test5"); test_basic_request(si.port, "GET", "/test6"); + test_basic_request(si.port, "GET", "/testF"); test_connection_header(si.port); test_http1_1(si.port); test_cookie_header(si.port); test_basic_authentication(si.port); test_invalid_response_headers(si.port); + test_response_without_headers(si.port); test_HttpQueryInfo(si.port); test_HttpSendRequestW(si.port); + test_last_error(si.port); /* send the basic request again to shutdown the server thread */ test_basic_request(si.port, "GET", "/quit"); @@ -2321,6 +2641,7 @@ struct notification unsigned int status; /* status received */ int async; /* delivered from another thread? */ int todo; + int optional; }; struct info @@ -2356,6 +2677,13 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW return; } + while (info->test[i].status != status && info->test[i].optional && + i < info->count - 1 && + info->test[i].function == info->test[i + 1].function) + { + i++; + } + status_ok = (info->test[i].status == status); function_ok = (info->test[i].function == info->function); @@ -2375,7 +2703,7 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW todo_wine ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function ); } if (i == info->count - 1 || info->test[i].function != info->test[i + 1].function) SetEvent( info->wait ); - info->index++; + info->index = i+1; LeaveCriticalSection( ¬ification_cs ); } @@ -2390,6 +2718,7 @@ static const struct notification async_send_request_ex_test[] = { { internet_connect, INTERNET_STATUS_HANDLE_CREATED, 0 }, { http_open_request, INTERNET_STATUS_HANDLE_CREATED, 0 }, + { http_send_request_ex, INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 }, { http_send_request_ex, INTERNET_STATUS_RESOLVING_NAME, 1 }, { http_send_request_ex, INTERNET_STATUS_NAME_RESOLVED, 1 }, { http_send_request_ex, INTERNET_STATUS_CONNECTING_TO_SERVER, 1 }, @@ -2493,6 +2822,7 @@ static void test_async_HttpSendRequestEx(void) InternetCloseHandle( ses ); WaitForSingleObject( info.wait, 10000 ); + Sleep(100); CloseHandle( info.wait ); } @@ -2548,8 +2878,11 @@ START_TEST(http) else { init_status_tests(); - InternetReadFile_test(INTERNET_FLAG_ASYNC); - InternetReadFile_test(0); + InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[0]); + InternetReadFile_test(0, &test_data[0]); + first_connection_to_test_url = TRUE; + InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[1]); + InternetReadFile_test(0, &test_data[1]); InternetReadFileExA_test(INTERNET_FLAG_ASYNC); test_open_url_async(); test_async_HttpSendRequestEx(); @@ -2557,9 +2890,10 @@ START_TEST(http) InternetOpenRequest_test(); test_http_cache(); InternetOpenUrlA_test(); - HttpSendRequestEx_test(); HttpHeaders_test(); test_http_connection(); test_user_agent_header(); test_bogus_accept_types_array(); + InternetReadFile_chunked_test(); + HttpSendRequestEx_test(); } diff --git a/rostests/winetests/wininet/internet.c b/rostests/winetests/wininet/internet.c index 176f3d8f648..fa28b0cbbb4 100644 --- a/rostests/winetests/wininet/internet.c +++ b/rostests/winetests/wininet/internet.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "wininet.h" #include "winerror.h" +#include "winreg.h" #include "wine/test.h" @@ -36,6 +37,18 @@ static BOOL (WINAPI *pInternetTimeFromSystemTimeW)(CONST SYSTEMTIME *,DWORD ,LPW static BOOL (WINAPI *pInternetTimeToSystemTimeA)(LPCSTR ,SYSTEMTIME *,DWORD); static BOOL (WINAPI *pInternetTimeToSystemTimeW)(LPCWSTR ,SYSTEMTIME *,DWORD); static BOOL (WINAPI *pIsDomainLegalCookieDomainW)(LPCWSTR, LPCWSTR); +static DWORD (WINAPI *pPrivacyGetZonePreferenceW)(DWORD, DWORD, LPDWORD, LPWSTR, LPDWORD); +static DWORD (WINAPI *pPrivacySetZonePreferenceW)(DWORD, DWORD, DWORD, LPCWSTR); + +/* Win9x and WinMe don't have lstrcmpW */ +static int strcmp_ww(const WCHAR *str1, const WCHAR *str2) +{ + DWORD len1 = lstrlenW(str1); + DWORD len2 = lstrlenW(str2); + + if (len1 != len2) return 1; + return memcmp(str1, str2, len1 * sizeof(WCHAR)); +} /* ############################### */ @@ -182,7 +195,7 @@ static void test_InternetQueryOptionA(void) if (retval) { ok(!strcmp(useragent,buffer),"Got wrong user agent string %s instead of %s\n",buffer,useragent); - todo_wine ok(len == strlen(useragent),"Got wrong user agent length %d instead of %d\n",len,lstrlenA(useragent)); + ok(len == strlen(useragent),"Got wrong user agent length %d instead of %d\n",len,lstrlenA(useragent)); } ok(err == 0xdeadbeef, "Got wrong error code %d\n",err); HeapFree(GetProcessHeap(),0,buffer); @@ -229,7 +242,7 @@ static void test_InternetQueryOptionA(void) len=0; retval=InternetQueryOptionA(hinet,INTERNET_OPTION_USER_AGENT,NULL,&len); err=GetLastError(); - todo_wine ok(len == 1,"Got wrong user agent length %d instead of %d\n",len,1); + ok(len == 1,"Got wrong user agent length %d instead of %d\n",len,1); ok(retval == 0,"Got wrong return value %d\n",retval); ok(err == ERROR_INSUFFICIENT_BUFFER, "Got wrong error code%d\n",err); @@ -463,7 +476,7 @@ static void test_null(void) ok( sz == 1 + lstrlenW(buffer) || sz == lstrlenW(buffer), "sz wrong %d\n", sz); /* before XP SP2, buffer is "server; server" */ - ok( !lstrcmpW(szExpect, buffer) || !lstrcmpW(szServer, buffer), "cookie data wrong\n"); + ok( !strcmp_ww(szExpect, buffer) || !strcmp_ww(szServer, buffer), "cookie data wrong\n"); sz = sizeof(buffer); r = InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, buffer, &sz); @@ -742,8 +755,9 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_SXS_KEY_NOT_FOUND || + error == ERROR_SUCCESS || /* IE8 on W2K3 */ error == 0xdeadbeef, /* up to IE7 */ - "got %u expected ERROR_SXS_KEY_NOT_FOUND or 0xdeadbeef\n", error); + "unexpected error: %u\n", error); ret = pIsDomainLegalCookieDomainW(gmail_com, gmail_com); ok(ret, "IsDomainLegalCookieDomainW failed\n"); @@ -754,9 +768,9 @@ static void test_IsDomainLegalCookieDomainW(void) ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_SXS_KEY_NOT_FOUND || /* IE8 on XP */ error == ERROR_FILE_NOT_FOUND || /* IE8 on Vista */ + error == ERROR_SUCCESS || /* IE8 on W2K3 */ error == 0xdeadbeef, /* up to IE7 */ - "got %u expected ERROR_SXS_KEY_NOT_FOUND, ERROR_FILE_NOT_FOUND or " - "0xdeadbeef\n", error); + "unexpected error: %u\n", error); ret = pIsDomainLegalCookieDomainW(uk, co_uk); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); @@ -794,6 +808,273 @@ static void test_IsDomainLegalCookieDomainW(void) ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); } +static void test_PrivacyGetSetZonePreferenceW(void) +{ + DWORD ret, zone, type, template, old_template; + + zone = 3; + type = 0; + ret = pPrivacyGetZonePreferenceW(zone, type, NULL, NULL, NULL); + ok(ret == 0, "expected ret == 0, got %u\n", ret); + + old_template = 0; + ret = pPrivacyGetZonePreferenceW(zone, type, &old_template, NULL, NULL); + ok(ret == 0, "expected ret == 0, got %u\n", ret); + + template = 5; + ret = pPrivacySetZonePreferenceW(zone, type, template, NULL); + ok(ret == 0, "expected ret == 0, got %u\n", ret); + + template = 0; + ret = pPrivacyGetZonePreferenceW(zone, type, &template, NULL, NULL); + ok(ret == 0, "expected ret == 0, got %u\n", ret); + ok(template == 5, "expected template == 5, got %u\n", template); + + template = 5; + ret = pPrivacySetZonePreferenceW(zone, type, old_template, NULL); + ok(ret == 0, "expected ret == 0, got %u\n", ret); +} + +static void test_Option_Policy(void) +{ + HINTERNET hinet; + BOOL ret; + + hinet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(hinet != 0, "InternetOpen failed: 0x%08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = InternetSetOptionW(hinet, INTERNET_OPTION_POLICY, NULL, 0); + ok(ret == FALSE, "InternetSetOption should've failed\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should've " + "given ERROR_INVALID_PARAMETER, gave: 0x%08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = InternetQueryOptionW(hinet, INTERNET_OPTION_POLICY, NULL, 0); + ok(ret == FALSE, "InternetQueryOption should've failed\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError should've " + "given ERROR_INVALID_PARAMETER, gave: 0x%08x\n", GetLastError()); + + ret = InternetCloseHandle(hinet); + ok(ret == TRUE, "InternetCloseHandle failed: 0x%08x\n", GetLastError()); +} + +#define verifyProxyEnable(e) r_verifyProxyEnable(__LINE__, e) +static void r_verifyProxyEnable(LONG l, DWORD exp) +{ + HKEY hkey; + DWORD type, val, size = sizeof(DWORD); + LONG ret; + static const CHAR szInternetSettings[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; + static const CHAR szProxyEnable[] = "ProxyEnable"; + + ret = RegOpenKeyA(HKEY_CURRENT_USER, szInternetSettings, &hkey); + ok_(__FILE__,l) (!ret, "RegOpenKeyA failed: 0x%08x\n", ret); + + ret = RegQueryValueExA(hkey, szProxyEnable, 0, &type, (BYTE*)&val, &size); + ok_(__FILE__,l) (!ret, "RegQueryValueExA failed: 0x%08x\n", ret); + ok_(__FILE__,l) (type == REG_DWORD, "Expected regtype to be REG_DWORD, was: %d\n", type); + ok_(__FILE__,l) (val == exp, "Expected ProxyEnabled to be %d, got: %d\n", exp, val); + + ret = RegCloseKey(hkey); + ok_(__FILE__,l) (!ret, "RegCloseKey failed: 0x%08x\n", ret); +} + +static void test_Option_PerConnectionOption(void) +{ + BOOL ret; + DWORD size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); + INTERNET_PER_CONN_OPTION_LISTW list = {size}; + INTERNET_PER_CONN_OPTIONW *orig_settings; + static WCHAR proxy_srvW[] = {'p','r','o','x','y','.','e','x','a','m','p','l','e',0}; + + /* get the global IE proxy server info, to restore later */ + list.dwOptionCount = 2; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + orig_settings = list.pOptions; + + /* set the global IE proxy server */ + list.dwOptionCount = 2; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[0].Value.pszValue = proxy_srvW; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY; + + ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* get & verify the global IE proxy server */ + list.dwOptionCount = 2; + list.dwOptionError = 0; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + ok(!strcmp_ww(list.pOptions[0].Value.pszValue, proxy_srvW), + "Retrieved proxy server should've been %s, was: %s\n", + wine_dbgstr_w(proxy_srvW), wine_dbgstr_w(list.pOptions[0].Value.pszValue)); + ok(list.pOptions[1].Value.dwValue == PROXY_TYPE_PROXY, + "Retrieved flags should've been PROXY_TYPE_PROXY, was: %d\n", + list.pOptions[1].Value.dwValue); + verifyProxyEnable(1); + + HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* disable the proxy server */ + list.dwOptionCount = 1; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT; + + ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* verify that the proxy is disabled */ + list.dwOptionCount = 1; + list.dwOptionError = 0; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + ok(list.pOptions[0].Value.dwValue == PROXY_TYPE_DIRECT, + "Retrieved flags should've been PROXY_TYPE_DIRECT, was: %d\n", + list.pOptions[0].Value.dwValue); + verifyProxyEnable(0); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* set the proxy flags to 'invalid' value */ + list.dwOptionCount = 1; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions[0].Value.dwValue = PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT; + + ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* verify that the proxy is enabled */ + list.dwOptionCount = 1; + list.dwOptionError = 0; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + todo_wine ok(list.pOptions[0].Value.dwValue == (PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT), + "Retrieved flags should've been PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT, was: %d\n", + list.pOptions[0].Value.dwValue); + verifyProxyEnable(1); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* restore original settings */ + list.dwOptionCount = 2; + list.pOptions = orig_settings; + + ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); +} + +static void test_Option_PerConnectionOptionA(void) +{ + BOOL ret; + DWORD size = sizeof(INTERNET_PER_CONN_OPTION_LISTA); + INTERNET_PER_CONN_OPTION_LISTA list = {size}; + INTERNET_PER_CONN_OPTIONA *orig_settings; + char proxy_srv[] = "proxy.example"; + + /* get the global IE proxy server info, to restore later */ + list.dwOptionCount = 2; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + orig_settings = list.pOptions; + + /* set the global IE proxy server */ + list.dwOptionCount = 2; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[0].Value.pszValue = proxy_srv; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY; + + ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* get & verify the global IE proxy server */ + list.dwOptionCount = 2; + list.dwOptionError = 0; + list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); + + list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + + ret = InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size); + ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); + ok(!lstrcmpA(list.pOptions[0].Value.pszValue, "proxy.example"), + "Retrieved proxy server should've been \"%s\", was: \"%s\"\n", + proxy_srv, list.pOptions[0].Value.pszValue); + ok(list.pOptions[1].Value.dwValue == PROXY_TYPE_PROXY, + "Retrieved flags should've been PROXY_TYPE_PROXY, was: %d\n", + list.pOptions[1].Value.dwValue); + + HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + HeapFree(GetProcessHeap(), 0, list.pOptions); + + /* restore original settings */ + list.dwOptionCount = 2; + list.pOptions = orig_settings; + + ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, size); + ok(ret == TRUE, "InternetSetOption should've succeeded\n"); + + HeapFree(GetProcessHeap(), 0, list.pOptions); +} + /* ############################### */ START_TEST(internet) @@ -807,6 +1088,8 @@ START_TEST(internet) pInternetTimeToSystemTimeA = (void*)GetProcAddress(hdll, "InternetTimeToSystemTimeA"); pInternetTimeToSystemTimeW = (void*)GetProcAddress(hdll, "InternetTimeToSystemTimeW"); pIsDomainLegalCookieDomainW = (void*)GetProcAddress(hdll, (LPCSTR)117); + pPrivacyGetZonePreferenceW = (void*)GetProcAddress(hdll, "PrivacyGetZonePreferenceW"); + pPrivacySetZonePreferenceW = (void*)GetProcAddress(hdll, "PrivacySetZonePreferenceW"); test_InternetCanonicalizeUrlA(); test_InternetQueryOptionA(); @@ -814,6 +1097,9 @@ START_TEST(internet) test_complicated_cookie(); test_version(); test_null(); + test_Option_Policy(); + test_Option_PerConnectionOption(); + test_Option_PerConnectionOptionA(); if (!pInternetTimeFromSystemTimeA) win_skip("skipping the InternetTime tests\n"); @@ -832,4 +1118,9 @@ START_TEST(internet) win_skip("IsDomainLegalCookieDomainW (or ordinal 117) is not available\n"); else test_IsDomainLegalCookieDomainW(); + + if (pPrivacyGetZonePreferenceW && pPrivacySetZonePreferenceW) + test_PrivacyGetSetZonePreferenceW(); + else + win_skip("Privacy[SG]etZonePreferenceW are not available\n"); } diff --git a/rostests/winetests/wininet/url.c b/rostests/winetests/wininet/url.c index 39c02863351..1f012f01422 100644 --- a/rostests/winetests/wininet/url.c +++ b/rostests/winetests/wininet/url.c @@ -23,21 +23,16 @@ #include #include #include +#include #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "wininet.h" #include "wine/test.h" -#define TEST_URL "http://www.winehq.org/site/about" -#define TEST_URL_HOST "www.winehq.org" -#define TEST_URL_PATH "/site/about" -#define TEST_URL2 "http://www.myserver.com/myscript.php?arg=1" -#define TEST_URL2_SERVER "www.myserver.com" -#define TEST_URL2_PATH "/myscript.php" -#define TEST_URL2_PATHEXTRA "/myscript.php?arg=1" -#define TEST_URL2_EXTRA "?arg=1" +#define TEST_URL "http://www.winehq.org/site/about#hi" #define TEST_URL3 "file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml" #define CREATE_URL1 "http://username:password@www.winehq.org/site/about" @@ -94,6 +89,190 @@ static void zero_compsA( SetLastError(0xfaceabad); } +typedef struct { + const char *url; + int scheme_off; + int scheme_len; + INTERNET_SCHEME scheme; + int host_off; + int host_len; + int host_skip_broken; + INTERNET_PORT port; + int user_off; + int user_len; + int pass_off; + int pass_len; + int path_off; + int path_len; + int extra_off; + int extra_len; +} crack_url_test_t; + +static const crack_url_test_t crack_url_tests[] = { + {"http://www.winehq.org/site/about#hi", + 0, 4, INTERNET_SCHEME_HTTP, 7, 14, -1, 80, -1, 0, -1, 0, 21, 11, 32, 3}, + {"http://www.myserver.com/myscript.php?arg=1", + 0, 4, INTERNET_SCHEME_HTTP, 7, 16, -1, 80, -1, 0, -1, 0, 23, 13, 36, 6}, + {"http://www.winehq.org?test=123", + 0, 4, INTERNET_SCHEME_HTTP, 7, 14, 23, 80, -1, 0, -1, 0, 21, 0, 21, 9}, + {"file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_FILE, -1, 0, -1, 0, -1, 0, -1, 0, 7, 55, -1, 0}, + {"fide:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_UNKNOWN, 7, 0, -1, 0, -1, 0, -1, 0, 7, 55, -1, 0}, + {"file://C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_FILE, -1, 0, -1, 0, -1, 0, -1, 0, 7, 54, -1, 0}, +}; + +static void test_crack_url(const crack_url_test_t *test) +{ + WCHAR buf[INTERNET_MAX_URL_LENGTH]; + URL_COMPONENTSW urlw; + URL_COMPONENTSA url; + BOOL b; + + zero_compsA(&url, 1, 1, 1, 1, 1, 1); + + b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url); + ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); + + if(test->scheme_off == -1) + ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme); + else + ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n", + test->url, url.lpszScheme, test->url+test->scheme_off); + ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n", + test->url, url.dwSchemeLength, test->scheme_len); + + ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme); + + if(test->host_off == -1) + ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName); + else + ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n", + test->url, url.lpszHostName, test->url+test->host_off); + if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) { + win_skip("skipping broken dwHostNameLength result\n"); + return; + } + ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n", + test->url, url.dwHostNameLength, test->host_len); + + ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port); + + if(test->user_off == -1) + ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName); + else + ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n", + test->url, url.lpszUserName, test->url+test->user_off); + ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n", + test->url, url.dwUserNameLength, test->user_len); + + if(test->pass_off == -1) + ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword); + else + ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n", + test->url, url.lpszPassword, test->url+test->pass_off); + ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n", + test->url, url.dwPasswordLength, test->pass_len); + + if(test->path_off == -1) + ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath); + else + ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n", + test->url, url.lpszUrlPath, test->url+test->path_off); + ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n", + test->url, url.dwUrlPathLength, test->path_len); + + if(test->extra_off == -1) + ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo); + else + ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n", + test->url, url.lpszExtraInfo, test->url+test->extra_off); + ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n", + test->url, url.dwExtraInfoLength, test->extra_len); + + memset(&urlw, 0, sizeof(URL_COMPONENTSW)); + urlw.dwStructSize = sizeof(URL_COMPONENTSW); + urlw.dwSchemeLength = 1; + urlw.dwHostNameLength = 1; + urlw.dwUserNameLength = 1; + urlw.dwPasswordLength = 1; + urlw.dwUrlPathLength = 1; + urlw.dwExtraInfoLength = 1; + + MultiByteToWideChar(CP_ACP, 0, test->url, -1, buf, sizeof(buf)); + b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw); + if(!b && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { + win_skip("InternetCrackUrlW is not implemented\n"); + return; + } + ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); + + if(test->scheme_off == -1) + ok(!urlw.lpszScheme, "[%s] urlw.lpszScheme = %p, expected NULL\n", test->url, urlw.lpszScheme); + else + ok(urlw.lpszScheme == buf+test->scheme_off, "[%s] urlw.lpszScheme = %p, expected %p\n", + test->url, urlw.lpszScheme, buf+test->scheme_off); + ok(urlw.dwSchemeLength == test->scheme_len, "[%s] urlw.lpszSchemeLength = %d, expected %d\n", + test->url, urlw.dwSchemeLength, test->scheme_len); + + ok(urlw.nScheme == test->scheme, "[%s] urlw.nScheme = %d, expected %d\n", test->url, urlw.nScheme, test->scheme); + + if(test->host_off == -1) { + ok(!urlw.lpszHostName, "[%s] urlw.lpszHostName = %p, expected NULL\n", test->url, urlw.lpszHostName); + ok(urlw.dwHostNameLength == 0 || broken(urlw.dwHostNameLength == 1), "[%s] urlw.lpszHostNameLength = %d, expected %d\n", + test->url, urlw.dwHostNameLength, test->host_len); + }else { + ok(urlw.lpszHostName == buf+test->host_off, "[%s] urlw.lpszHostName = %p, expected %p\n", + test->url, urlw.lpszHostName, test->url+test->host_off); + ok(urlw.dwHostNameLength == test->host_len, "[%s] urlw.lpszHostNameLength = %d, expected %d\n", + test->url, urlw.dwHostNameLength, test->host_len); + } + + ok(urlw.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, urlw.nPort, test->port); + + if(test->user_off == -1) { + ok(!urlw.lpszUserName, "[%s] urlw.lpszUserName = %p\n", test->url, urlw.lpszUserName); + ok(urlw.dwUserNameLength == 0 || broken(urlw.dwUserNameLength == 1), "[%s] urlw.lpszUserNameLength = %d, expected %d\n", + test->url, urlw.dwUserNameLength, test->user_len); + }else { + ok(urlw.lpszUserName == buf+test->user_off, "[%s] urlw.lpszUserName = %p, expected %p\n", + test->url, urlw.lpszUserName, buf+test->user_off); + ok(urlw.dwUserNameLength == test->user_len, "[%s] urlw.lpszUserNameLength = %d, expected %d\n", + test->url, urlw.dwUserNameLength, test->user_len); + } + + if(test->pass_off == -1) { + ok(!urlw.lpszPassword, "[%s] urlw.lpszPassword = %p\n", test->url, urlw.lpszPassword); + ok(urlw.dwPasswordLength == 0 || broken(urlw.dwPasswordLength), "[%s] urlw.lpszPasswordLength = %d, expected %d\n", + test->url, urlw.dwPasswordLength, test->pass_len); + }else { + ok(urlw.lpszPassword == buf+test->pass_off, "[%s] urlw.lpszPassword = %p, expected %p\n", + test->url, urlw.lpszPassword, buf+test->pass_off); + ok(urlw.dwPasswordLength == test->pass_len, "[%s] urlw.lpszPasswordLength = %d, expected %d\n", + test->url, urlw.dwPasswordLength, test->pass_len); + } + + if(test->path_off == -1) + ok(!urlw.lpszUrlPath, "[%s] urlw.lpszPath = %p, expected NULL\n", test->url, urlw.lpszUrlPath); + else + ok(urlw.lpszUrlPath == buf+test->path_off, "[%s] urlw.lpszPath = %p, expected %p\n", + test->url, urlw.lpszUrlPath, buf+test->path_off); + ok(urlw.dwUrlPathLength == test->path_len, "[%s] urlw.lpszUrlPathLength = %d, expected %d\n", + test->url, urlw.dwUrlPathLength, test->path_len); + + if(test->extra_off == -1) { + ok(!urlw.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, urlw.lpszExtraInfo); + ok(urlw.dwExtraInfoLength == 0 || broken(urlw.dwExtraInfoLength == 1), "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", + test->url, urlw.dwExtraInfoLength, test->extra_len); + }else { + ok(urlw.lpszExtraInfo == buf+test->extra_off, "[%s] urlw.lpszExtraInfo = %p, expected %p\n", + test->url, urlw.lpszExtraInfo, buf+test->extra_off); + ok(urlw.dwExtraInfoLength == test->extra_len, "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", + test->url, urlw.dwExtraInfoLength, test->extra_len); + } +} + static void InternetCrackUrl_test(void) { URL_COMPONENTSA urlSrc, urlComponents; @@ -111,51 +290,6 @@ static void InternetCrackUrl_test(void) urlSrc.lpszUrlPath = path; urlSrc.lpszExtraInfo = extra; - copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024); - ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents); - ok( ret, "InternetCrackUrl failed, error %d\n",GetLastError()); - ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n"); - - /* Bug 1805: Confirm the returned lengths are correct: */ - /* 1. When extra info split out explicitly */ - zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 1); - ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed, error %d\n", GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATH),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATH), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATH,strlen(TEST_URL2_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATH, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName); - ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL2_EXTRA),".dwExtraInfoLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_EXTRA), urlComponents.dwExtraInfoLength); - ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL2_EXTRA,strlen(TEST_URL2_EXTRA)),"lpszExtraInfo should be %s but is %s\n", TEST_URL2_EXTRA, urlComponents.lpszHostName); - - /* 2. When extra info is not split out explicitly and is in url path */ - zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 0); - ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATHEXTRA),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATHEXTRA), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATHEXTRA,strlen(TEST_URL2_PATHEXTRA)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATHEXTRA, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName); - ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort); - ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme); - - zero_compsA(&urlComponents, 1, 1, 1, 1, 1, 1); - ok(InternetCrackUrlA(TEST_URL, strlen(TEST_URL), 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL_PATH),".dwUrlPathLength should be %d, but is %d\n", lstrlenA(TEST_URL_PATH), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL_PATH,strlen(TEST_URL_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL_PATH, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL_HOST),".dwHostNameLength should be %d, but is %d\n", lstrlenA(TEST_URL_HOST), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL_HOST,strlen(TEST_URL_HOST)),"lpszHostName should be %s but is %s\n", TEST_URL_HOST, urlComponents.lpszHostName); - ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort); - ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme); - ok(!urlComponents.lpszUserName, ".lpszUserName should have been set to NULL\n"); - ok(!urlComponents.lpszPassword, ".lpszPassword should have been set to NULL\n"); - ok(!urlComponents.lpszExtraInfo, ".lpszExtraInfo should have been set to NULL\n"); - ok(!urlComponents.dwUserNameLength,".dwUserNameLength should be 0, but is %d\n", urlComponents.dwUserNameLength); - ok(!urlComponents.dwPasswordLength,".dwPasswordLength should be 0, but is %d\n", urlComponents.dwPasswordLength); - ok(!urlComponents.dwExtraInfoLength,".dwExtraInfoLength should be 0, but is %d\n", urlComponents.dwExtraInfoLength); - - /*3. Check for %20 */ - copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024); - ok(InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - /* Tests for lpsz* members pointing to real strings while * some corresponding length members are set to zero. * As of IE7 (wininet 7.0*?) all members are checked. So we @@ -810,6 +944,11 @@ static void InternetCreateUrlA_test(void) START_TEST(url) { + int i; + + for(i=0; i < sizeof(crack_url_tests)/sizeof(*crack_url_tests); i++) + test_crack_url(crack_url_tests+i); + InternetCrackUrl_test(); InternetCrackUrlW_test(); InternetCreateUrlA_test(); diff --git a/rostests/winetests/wininet/urlcache.c b/rostests/winetests/wininet/urlcache.c index d13597626de..65e433c69de 100644 --- a/rostests/winetests/wininet/urlcache.c +++ b/rostests/winetests/wininet/urlcache.c @@ -25,15 +25,18 @@ #include "windef.h" #include "winbase.h" #include "wininet.h" +#include "winineti.h" #include "wine/test.h" #define TEST_URL "http://urlcachetest.winehq.org/index.html" +#define TEST_URL1 "Visited: user@http://urlcachetest.winehq.org/index.html" static BOOL (WINAPI *pDeleteUrlCacheEntryA)(LPCSTR); static BOOL (WINAPI *pUnlockUrlCacheEntryFileA)(LPCSTR,DWORD); static char filenameA[MAX_PATH + 1]; +static char filenameA1[MAX_PATH + 1]; static void check_cache_entry_infoA(const char *returnedfrom, LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo) { @@ -53,6 +56,7 @@ static void test_find_url_cache_entriesA(void) LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo; cbCacheEntryInfo = 0; + SetLastError(0xdeadbeef); hEnumHandle = FindFirstUrlCacheEntry(NULL, NULL, &cbCacheEntryInfo); ok(!hEnumHandle, "FindFirstUrlCacheEntry should have failed\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "FindFirstUrlCacheEntry should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); @@ -67,6 +71,7 @@ static void test_find_url_cache_entriesA(void) found = TRUE; break; } + SetLastError(0xdeadbeef); cbCacheEntryInfo = cbCacheEntryInfoSaved; ret = FindNextUrlCacheEntry(hEnumHandle, lpCacheEntryInfo, &cbCacheEntryInfo); if (!ret) @@ -94,19 +99,37 @@ static void test_GetUrlCacheEntryInfoExA(void) DWORD cbCacheEntryInfo; LPINTERNET_CACHE_ENTRY_INFO lpCacheEntryInfo; + SetLastError(0xdeadbeef); ret = GetUrlCacheEntryInfoEx(NULL, NULL, NULL, NULL, NULL, NULL, 0); ok(!ret, "GetUrlCacheEntryInfoEx with NULL URL and NULL args should have failed\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetUrlCacheEntryInfoEx with NULL URL and NULL args should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "GetUrlCacheEntryInfoEx with NULL URL and NULL args should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); + + cbCacheEntryInfo = sizeof(INTERNET_CACHE_ENTRY_INFO); + SetLastError(0xdeadbeef); + ret = GetUrlCacheEntryInfoEx("", NULL, &cbCacheEntryInfo, NULL, NULL, NULL, 0); + ok(!ret, "GetUrlCacheEntryInfoEx with zero-length buffer should fail\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, + "GetUrlCacheEntryInfoEx should have set last error to ERROR_FILE_NOT_FOUND instead of %d\n", GetLastError()); ret = GetUrlCacheEntryInfoEx(TEST_URL, NULL, NULL, NULL, NULL, NULL, 0); ok(ret, "GetUrlCacheEntryInfoEx with NULL args failed with error %d\n", GetLastError()); cbCacheEntryInfo = 0; + SetLastError(0xdeadbeef); ret = GetUrlCacheEntryInfoEx(TEST_URL, NULL, &cbCacheEntryInfo, NULL, NULL, NULL, 0); ok(!ret, "GetUrlCacheEntryInfoEx with zero-length buffer should fail\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetUrlCacheEntryInfoEx should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "GetUrlCacheEntryInfoEx should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); lpCacheEntryInfo = HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo); + + SetLastError(0xdeadbeef); + ret = GetUrlCacheEntryInfoEx(TEST_URL, lpCacheEntryInfo, &cbCacheEntryInfo, NULL, NULL, NULL, 0x200); + ok(!ret, "GetUrlCacheEntryInfoEx succeeded\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, + "GetUrlCacheEntryInfoEx should have set last error to ERROR_FILE_NOT_FOUND instead of %d\n", GetLastError()); + ret = GetUrlCacheEntryInfoEx(TEST_URL, lpCacheEntryInfo, &cbCacheEntryInfo, NULL, NULL, NULL, 0); ok(ret, "GetUrlCacheEntryInfoEx failed with error %d\n", GetLastError()); @@ -161,6 +184,11 @@ static void test_urlcacheA(void) ret = CreateUrlCacheEntry(TEST_URL, 0, "html", filenameA, 0); ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError()); + ret = CreateUrlCacheEntry(TEST_URL, 0, "html", filenameA1, 0); + ok(ret, "CreateUrlCacheEntry failed with error %d\n", GetLastError()); + + ok(lstrcmpiA(filenameA, filenameA1), "expected a different file name\n"); + hFile = CreateFileA(filenameA, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA failed with error %d\n", GetLastError()); @@ -170,13 +198,21 @@ static void test_urlcacheA(void) CloseHandle(hFile); + ret = CommitUrlCacheEntry(TEST_URL1, NULL, filetime_zero, filetime_zero, NORMAL_CACHE_ENTRY|URLHISTORY_CACHE_ENTRY, NULL, 0, NULL, NULL); + ok(ret, "CommitUrlCacheEntry failed with error %d\n", GetLastError()); + + ret = CommitUrlCacheEntry(TEST_URL1, NULL, filetime_zero, filetime_zero, NORMAL_CACHE_ENTRY|URLHISTORY_CACHE_ENTRY, NULL, 0, NULL, NULL); + ok(ret, "CommitUrlCacheEntry failed with error %d\n", GetLastError()); + ret = CommitUrlCacheEntry(TEST_URL, filenameA, filetime_zero, filetime_zero, NORMAL_CACHE_ENTRY, NULL, 0, "html", NULL); ok(ret, "CommitUrlCacheEntry failed with error %d\n", GetLastError()); cbCacheEntryInfo = 0; + SetLastError(0xdeadbeef); ret = RetrieveUrlCacheEntryFile(TEST_URL, NULL, &cbCacheEntryInfo, 0); ok(!ret, "RetrieveUrlCacheEntryFile should have failed\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "RetrieveUrlCacheEntryFile should have set last error to ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); lpCacheEntryInfo = HeapAlloc(GetProcessHeap(), 0, cbCacheEntryInfo); ret = RetrieveUrlCacheEntryFile(TEST_URL, lpCacheEntryInfo, &cbCacheEntryInfo, 0); @@ -186,6 +222,13 @@ static void test_urlcacheA(void) HeapFree(GetProcessHeap(), 0, lpCacheEntryInfo); + cbCacheEntryInfo = 0; + SetLastError(0xdeadbeef); + ret = RetrieveUrlCacheEntryFile(TEST_URL1, NULL, &cbCacheEntryInfo, 0); + ok(!ret, "RetrieveUrlCacheEntryFile should have failed\n"); + ok(GetLastError() == ERROR_INVALID_DATA, + "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_DATA instead of %d\n", GetLastError()); + if (pUnlockUrlCacheEntryFileA) { ret = pUnlockUrlCacheEntryFileA(TEST_URL, 0); @@ -202,8 +245,11 @@ static void test_urlcacheA(void) { ret = pDeleteUrlCacheEntryA(TEST_URL); ok(ret, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError()); + ret = pDeleteUrlCacheEntryA(TEST_URL1); + ok(ret, "DeleteUrlCacheEntryA failed with error %d\n", GetLastError()); } + SetLastError(0xdeadbeef); ret = DeleteFile(filenameA); todo_wine ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "local file should no longer exist\n"); @@ -213,12 +259,54 @@ static void test_FindCloseUrlCache(void) { BOOL r; DWORD err; + + SetLastError(0xdeadbeef); r = FindCloseUrlCache(NULL); err = GetLastError(); ok(0 == r, "expected 0, got %d\n", r); ok(ERROR_INVALID_HANDLE == err, "expected %d, got %d\n", ERROR_INVALID_HANDLE, err); } +static void test_GetDiskInfoA(void) +{ + BOOL ret; + DWORD error, cluster_size; + DWORDLONG free, total; + char path[MAX_PATH], *p; + + GetSystemDirectoryA(path, MAX_PATH); + if ((p = strchr(path, '\\'))) *++p = 0; + + ret = GetDiskInfoA(path, &cluster_size, &free, &total); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, &cluster_size, &free, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, &cluster_size, NULL, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + ret = GetDiskInfoA(path, NULL, NULL, NULL); + ok(ret, "GetDiskInfoA failed %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + strcpy(p, "\\non\\existing\\path"); + ret = GetDiskInfoA(path, NULL, NULL, NULL); + error = GetLastError(); + ok(!ret || + broken(ret), /* < IE7 */ + "GetDiskInfoA succeeded\n"); + ok(error == ERROR_PATH_NOT_FOUND || + broken(error == 0xdeadbeef), /* < IE7 */ + "got %u expected ERROR_PATH_NOT_FOUND\n", error); + + SetLastError(0xdeadbeef); + ret = GetDiskInfoA(NULL, NULL, NULL, NULL); + error = GetLastError(); + ok(!ret, "GetDiskInfoA succeeded\n"); + ok(error == ERROR_INVALID_PARAMETER, "got %u expected ERROR_INVALID_PARAMETER\n", error); +} + START_TEST(urlcache) { HMODULE hdll; @@ -227,4 +315,5 @@ START_TEST(urlcache) pUnlockUrlCacheEntryFileA = (void*)GetProcAddress(hdll, "UnlockUrlCacheEntryFileA"); test_urlcacheA(); test_FindCloseUrlCache(); + test_GetDiskInfoA(); } diff --git a/rostests/winetests/wininet/wininet.rbuild b/rostests/winetests/wininet/wininet.rbuild index 4edfeed88fd..f1ce89a34a3 100644 --- a/rostests/winetests/wininet/wininet.rbuild +++ b/rostests/winetests/wininet/wininet.rbuild @@ -3,10 +3,11 @@ . - + wine wininet ws2_32 + advapi32 ntdll ftp.c generated.c