mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Compare commits
27 commits
44e833ab3e
...
529757ef1b
Author | SHA1 | Date | |
---|---|---|---|
|
529757ef1b | ||
|
b76b4c9a27 | ||
|
ae6366b33c | ||
|
d9cf4678a1 | ||
|
da936bcf35 | ||
|
e75192fe72 | ||
|
0dc7e40468 | ||
|
700ee59470 | ||
|
c76a192bf6 | ||
|
9acdc03128 | ||
|
8b121591be | ||
|
5a23afb34d | ||
|
6a01532899 | ||
|
e5b0ead2b5 | ||
|
b9c06c4474 | ||
|
a57eedec86 | ||
|
9212706ede | ||
|
40b314cf34 | ||
|
aa24458086 | ||
|
576d7e24cd | ||
|
305ec347dc | ||
|
4c0103e58c | ||
|
1137a10ef7 | ||
|
eae7db4fa4 | ||
|
75e2ec479b | ||
|
45953cdbec | ||
|
126c54cd25 |
37 changed files with 7399 additions and 7172 deletions
64
.gitattributes
vendored
Normal file
64
.gitattributes
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
[attr]generated gitlab-generated linguist-generated=true
|
||||
|
||||
# generated by autotools
|
||||
configure generated
|
||||
include/config.h.in generated
|
||||
|
||||
# generated by dlls/dsound/make_fir
|
||||
dlls/dsound/fir.h generated
|
||||
|
||||
# generated by dlls/opencl/make_opencl
|
||||
dlls/opencl/opencl.spec generated
|
||||
dlls/opencl/opencl_types.h generated
|
||||
dlls/opencl/pe_thunks.c generated
|
||||
dlls/opencl/unix_thunks.c generated
|
||||
dlls/opencl/unixlib.h generated
|
||||
|
||||
# generated by dlls/opengl32/make_opengl
|
||||
dlls/opengl32/opengl32.spec generated
|
||||
dlls/opengl32/thunks.c generated
|
||||
dlls/opengl32/unix_thunks.c generated
|
||||
dlls/opengl32/unixlib.h generated
|
||||
include/wine/wgl.h generated
|
||||
include/wine/wgl_driver.h generated
|
||||
|
||||
# generated by dlls/winevulkan/make_vulkan
|
||||
dlls/vulkan-1/vulkan-1.spec generated
|
||||
dlls/winevulkan/loader_thunks.c generated
|
||||
dlls/winevulkan/loader_thunks.h generated
|
||||
dlls/winevulkan/vulkan_thunks.c generated
|
||||
dlls/winevulkan/vulkan_thunks.h generated
|
||||
dlls/winevulkan/winevulkan.json generated
|
||||
dlls/winevulkan/winevulkan.spec generated
|
||||
include/wine/vulkan.h generated
|
||||
include/wine/vulkan_driver.h generated
|
||||
|
||||
# generated by tools/make_requests
|
||||
include/wine/server_protocol.h generated
|
||||
server/request_handlers.h generated
|
||||
server/request_trace.h generated
|
||||
|
||||
# generated by tools/make_specfiles
|
||||
dlls/ntdll/ntsyscalls.h generated
|
||||
dlls/win32u/win32syscalls.h generated
|
||||
|
||||
# generated by tools/make_unicode
|
||||
dlls/dwrite/bracket.c generated
|
||||
dlls/dwrite/direction.c generated
|
||||
dlls/dwrite/linebreak.c generated
|
||||
dlls/dwrite/mirror.c generated
|
||||
dlls/dwrite/scripts.c generated
|
||||
dlls/dwrite/scripts.h generated
|
||||
dlls/dwrite/shapers/arabic_table.c generated
|
||||
dlls/gdi32/uniscribe/bracket.c generated
|
||||
dlls/gdi32/uniscribe/direction.c generated
|
||||
dlls/gdi32/uniscribe/indicsyllable.c generated
|
||||
dlls/gdi32/uniscribe/linebreak.c generated
|
||||
dlls/gdi32/uniscribe/mirror.c generated
|
||||
dlls/gdi32/uniscribe/shaping.c generated
|
||||
dlls/kernelbase/kernelbase.rgs generated
|
||||
dlls/tzres/tzres.rc generated
|
||||
dlls/win32u/vertical.c generated
|
||||
dlls/wineps.drv/direction.c generated
|
||||
dlls/wineps.drv/vertical.c generated
|
||||
nls/*.nls generated
|
|
@ -4150,6 +4150,7 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* see if we are supposed to be tracking mouse hovering */
|
||||
if (LISTVIEW_IsHotTracking(infoPtr)) {
|
||||
TRACKMOUSEEVENT trackinfo;
|
||||
NMLISTVIEW nmlv = { 0 };
|
||||
DWORD flags;
|
||||
|
||||
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
|
@ -4170,6 +4171,15 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
|
|||
/* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */
|
||||
_TrackMouseEvent(&trackinfo);
|
||||
}
|
||||
|
||||
ht.pt = pt;
|
||||
LISTVIEW_HitTest(infoPtr, &ht, TRUE, TRUE);
|
||||
|
||||
nmlv.iItem = ht.iItem;
|
||||
nmlv.iSubItem = ht.iSubItem;
|
||||
nmlv.ptAction = pt;
|
||||
|
||||
notify_listview(infoPtr, LVN_HOTTRACK, &nmlv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -9585,6 +9595,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
|
|||
infoPtr->iVersion = COMCTL32_VERSION;
|
||||
infoPtr->colRectsDirty = FALSE;
|
||||
infoPtr->selected_column = -1;
|
||||
infoPtr->hHotCursor = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
|
||||
|
||||
/* get default font (icon title) */
|
||||
SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
|
||||
|
|
|
@ -7255,6 +7255,19 @@ static void test_LVM_GETNEXTITEM(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_LVM_GETHOTCURSOR(void)
|
||||
{
|
||||
HCURSOR cursor;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = create_listview_control(LVS_REPORT);
|
||||
|
||||
cursor = (HCURSOR)SendMessageA(hwnd, LVM_GETHOTCURSOR, 0, 0);
|
||||
ok(!!cursor, "Unexpected cursor %p.\n", cursor);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(listview)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -7322,6 +7335,7 @@ START_TEST(listview)
|
|||
test_LVM_SETBKIMAGE(FALSE);
|
||||
test_custom_sort();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
{
|
||||
|
@ -7372,6 +7386,7 @@ START_TEST(listview)
|
|||
test_LVM_GETNEXTITEMINDEX();
|
||||
test_LVM_GETNEXTITEM();
|
||||
test_LVM_SETBKIMAGE(TRUE);
|
||||
test_LVM_GETHOTCURSOR();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
|
||||
|
|
|
@ -179,13 +179,47 @@ static BOOL equal_dc(HDC hdc1, HDC hdc2, int width, int height)
|
|||
|
||||
static void *alloced_str;
|
||||
|
||||
static LRESULT parent_wnd_notify(LPARAM lParam)
|
||||
static const NMCBEENDEDITW test_WM_NOTIFY_NMCBEENDEDITW =
|
||||
{
|
||||
.hdr.hwndFrom = (HWND)0xabcd0001,
|
||||
.hdr.idFrom = 0xabcd0002,
|
||||
.hdr.code = CBEN_ENDEDITW,
|
||||
.fChanged = 0xabcd0003,
|
||||
.iNewSelection = 0xabcd0004,
|
||||
.szText = {'L','o','r','e','m',' ','i','p','s','u','m',' ','d','o','l','o','r',' ','s','i','t',' ','a','m','e','t',0},
|
||||
.iWhy = 0xabcd0005
|
||||
};
|
||||
static const NMCBEENDEDITA test_WM_NOTIFY_NMCBEENDEDITA =
|
||||
{
|
||||
.hdr.hwndFrom = (HWND)0xabcd0001,
|
||||
.hdr.idFrom = 0xabcd0002,
|
||||
.hdr.code = CBEN_ENDEDITA,
|
||||
.fChanged = 0xabcd0003,
|
||||
.iNewSelection = 0xabcd0004,
|
||||
.szText = {'L','o','r','e','m',' ','i','p','s','u','m',' ','d','o','l','o','r',' ','s','i','t',' ','a','m','e','t',0},
|
||||
.iWhy = 0xabcd0005
|
||||
};
|
||||
static BOOL test_WM_NOTIFY_expect_CBEN_ENDEDITA;
|
||||
|
||||
static LRESULT parent_wnd_notify(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
NMHDR *hdr = (NMHDR *)lParam;
|
||||
NMTBHOTITEM *nmhi;
|
||||
NMTBDISPINFOA *nmdisp;
|
||||
switch (hdr->code)
|
||||
{
|
||||
case CBEN_ENDEDITA:
|
||||
if (test_WM_NOTIFY_expect_CBEN_ENDEDITA)
|
||||
{
|
||||
test_WM_NOTIFY_expect_CBEN_ENDEDITA = FALSE;
|
||||
ok(!memcmp(hdr, &test_WM_NOTIFY_NMCBEENDEDITA, sizeof(NMCBEENDEDITA)), "Incorrectly converted NMCBEENDEDITW to NMCBEENDEDITA.\n");
|
||||
ok(wParam == 0xabcd0002, "Got unexpected wParam 0x%Ix.\n", wParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(FALSE, "Got unexpected WM_NOTIFY.\n");
|
||||
}
|
||||
return 0xabcd0006;
|
||||
case TBN_HOTITEMCHANGE:
|
||||
nmhi = (NMTBHOTITEM *)lParam;
|
||||
g_fReceivedHotItemChange = TRUE;
|
||||
|
@ -428,7 +462,7 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
switch (message)
|
||||
{
|
||||
case WM_NOTIFY:
|
||||
return parent_wnd_notify(lParam);
|
||||
return parent_wnd_notify(wParam, lParam);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
|
@ -2833,6 +2867,20 @@ static void test_BTNS_SEP(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_WM_NOTIFY(void)
|
||||
{
|
||||
HWND toolbar = NULL;
|
||||
LRESULT ret;
|
||||
|
||||
rebuild_toolbar(&toolbar);
|
||||
test_WM_NOTIFY_expect_CBEN_ENDEDITA = TRUE;
|
||||
ret = SendMessageA(toolbar, WM_NOTIFY, 0, (LPARAM)&test_WM_NOTIFY_NMCBEENDEDITW);
|
||||
ok(ret == 0xabcd0006, "SendMessageA returned 0x%Ix.\n", ret);
|
||||
ok(!test_WM_NOTIFY_expect_CBEN_ENDEDITA, "Toolbar didn't convert and forward WM_NOTIFY to parent.\n");
|
||||
test_WM_NOTIFY_expect_CBEN_ENDEDITA = FALSE;
|
||||
DestroyWindow(toolbar);
|
||||
}
|
||||
|
||||
START_TEST(toolbar)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -2884,6 +2932,7 @@ START_TEST(toolbar)
|
|||
test_drawtext_flags();
|
||||
test_imagelist();
|
||||
test_BTNS_SEP();
|
||||
test_WM_NOTIFY();
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &ctx))
|
||||
return;
|
||||
|
|
|
@ -6359,6 +6359,24 @@ TOOLBAR_Notify (TOOLBAR_INFO *infoPtr, LPNMHDR lpnmh)
|
|||
FIXME("TTN_GETDISPINFOA - should not be received; please report\n");
|
||||
return 0;
|
||||
|
||||
/* FIXME: CBEN_ENDEDITW is just 1 of 4294967244 codes that should be forwarded */
|
||||
case CBEN_ENDEDITW:
|
||||
if (!infoPtr->bUnicode)
|
||||
{
|
||||
NMCBEENDEDITW *nmedW = (NMCBEENDEDITW *)lpnmh;
|
||||
NMCBEENDEDITA nmedA = {{0}};
|
||||
nmedA.hdr.code = CBEN_ENDEDITA;
|
||||
nmedA.hdr.hwndFrom = nmedW->hdr.hwndFrom;
|
||||
nmedA.hdr.idFrom = nmedW->hdr.idFrom;
|
||||
nmedA.fChanged = nmedW->fChanged;
|
||||
nmedA.iNewSelection = nmedW->iNewSelection;
|
||||
nmedA.iWhy = nmedW->iWhy;
|
||||
WideCharToMultiByte(CP_ACP, 0, nmedW->szText, ARRAY_SIZE(nmedW->szText), nmedA.szText, ARRAY_SIZE(nmedA.szText),
|
||||
NULL, FALSE);
|
||||
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, lpnmh->idFrom, (LPARAM)&nmedA);
|
||||
}
|
||||
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, lpnmh->idFrom, (LPARAM)lpnmh);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4379,7 +4379,13 @@ static BOOL codeview_process_info(const struct process *pcs,
|
|||
|
||||
TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
|
||||
wine_dbgstr_guid(&rsds->guid), rsds->age, debugstr_a(rsds->name));
|
||||
/* gcc/mingw and clang can emit build-id information, but with an empty PDB filename.
|
||||
* Don't search for the .pdb file in that case.
|
||||
*/
|
||||
if (rsds->name[0])
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
else
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -4487,7 +4493,7 @@ typedef struct _FPO_DATA
|
|||
__ENDTRY
|
||||
|
||||
/* we haven't found yet any debug information, fallback to unmatched pdb */
|
||||
if (module->module.SymType == SymDeferred)
|
||||
if (!ret && module->module.SymType == SymDeferred)
|
||||
{
|
||||
SYMSRV_INDEX_INFOW info = {.sizeofstruct = sizeof(info)};
|
||||
char buffer[MAX_PATH];
|
||||
|
@ -4549,38 +4555,35 @@ DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* debug_dir
|
|||
num_misc_records++;
|
||||
}
|
||||
}
|
||||
return info->stripped && !num_misc_records ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
return (!num_dir || (info->stripped && !num_misc_records)) ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||
{
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER *header;
|
||||
IMAGE_DEBUG_DIRECTORY *dbg;
|
||||
DWORD num_directories;
|
||||
|
||||
if (size < sizeof(*header)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (size < sizeof(*header)) return ERROR_BAD_FORMAT;
|
||||
header = image;
|
||||
if (header->Signature != 0x4944 /* DI */ ||
|
||||
size < sizeof(*header) + header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + header->ExportedNamesSize + header->DebugDirectorySize)
|
||||
return ERROR_BAD_EXE_FORMAT;
|
||||
return ERROR_BAD_FORMAT;
|
||||
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
/* header is followed by:
|
||||
* - header->NumberOfSections of IMAGE_SECTION_HEADER
|
||||
* - header->ExportedNameSize
|
||||
* - then num_directories of IMAGE_DEBUG_DIRECTORY
|
||||
*/
|
||||
dbg = (IMAGE_DEBUG_DIRECTORY*)((char*)(header + 1) +
|
||||
header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header->ExportedNamesSize);
|
||||
num_directories = header->DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
if (!num_directories) return ERROR_BAD_EXE_FORMAT;
|
||||
|
||||
info->age = 0;
|
||||
memset(&info->guid, 0, sizeof(info->guid));
|
||||
info->sig = 0;
|
||||
info->dbgfile[0] = L'\0';
|
||||
info->pdbfile[0] = L'\0';
|
||||
info->size = header->SizeOfImage;
|
||||
/* seems to use header's timestamp, not debug_directory one */
|
||||
info->timestamp = header->TimeDateStamp;
|
||||
info->stripped = FALSE; /* FIXME */
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
return msc_get_file_indexinfo(image, dbg, num_directories, info);
|
||||
}
|
||||
|
|
|
@ -832,7 +832,7 @@ BOOL WINAPI SymSrvGetFileIndexInfoW(const WCHAR *file, SYMSRV_INDEX_INFOW* info,
|
|||
if (hMap) CloseHandle(hMap);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
|
||||
if (ret == ERROR_SUCCESS) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
if (ret == ERROR_SUCCESS || ret == ERROR_BAD_EXE_FORMAT) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
SetLastError(ret);
|
||||
return ret == ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -656,7 +656,7 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
|
|||
if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
|
||||
misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
|
||||
{
|
||||
ERR("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
WARN("-Debug info stripped, but no .DBG file in module %s\n",
|
||||
debugstr_w(module->modulename));
|
||||
}
|
||||
else
|
||||
|
@ -1019,7 +1019,7 @@ DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
|||
if (!(nthdr = RtlImageNtHeader(image))) return ERROR_BAD_FORMAT;
|
||||
|
||||
dbg = RtlImageDirectoryEntryToData(image, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dirsize);
|
||||
if (!dbg || dirsize < sizeof(dbg)) return ERROR_BAD_EXE_FORMAT;
|
||||
if (!dbg) dirsize = 0;
|
||||
|
||||
/* fill in information from NT header */
|
||||
info->timestamp = nthdr->FileHeader.TimeDateStamp;
|
||||
|
|
|
@ -671,20 +671,22 @@ static BOOL create_test_pdb_ds(const WCHAR* pdb_name, const GUID* guid, DWORD ag
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp, DWORD size)
|
||||
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD charac, DWORD timestamp, DWORD size, struct debug_directory_blob *blob)
|
||||
{
|
||||
HANDLE hfile;
|
||||
|
||||
/* minimalistic .dbg made of a header and a DEBUG_DIRECTORY without any data */
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER header = {.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = 0x010E, .TimeDateStamp = timestamp,
|
||||
IMAGE_SEPARATE_DEBUG_HEADER header =
|
||||
{
|
||||
.Signature = 0x4944 /* DI */,
|
||||
.Flags = 0, .Machine = machine, .Characteristics = charac, .TimeDateStamp = timestamp,
|
||||
.CheckSum = 0, .ImageBase = 0x00040000, .SizeOfImage = size, .NumberOfSections = 0,
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY)};
|
||||
const IMAGE_DEBUG_DIRECTORY debug_dir = {.Characteristics = 0, .TimeDateStamp = timestamp + 1,
|
||||
.MajorVersion = 0, .MinorVersion = 0, .Type = IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
.SizeOfData = 0, .AddressOfRawData = 0,
|
||||
.PointerToRawData = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
header.DebugDirectorySize};
|
||||
.ExportedNamesSize = 0, .DebugDirectorySize = 0
|
||||
};
|
||||
DWORD where, expected_size;
|
||||
|
||||
if (blob)
|
||||
header.DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
|
||||
hfile = CreateFileW(dbg_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
|
||||
ok(hfile != INVALID_HANDLE_VALUE, "failed to create %ls err %lu\n", dbg_name, GetLastError());
|
||||
|
@ -692,8 +694,18 @@ static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp
|
|||
|
||||
check_write_file(hfile, &header, sizeof(header));
|
||||
/* FIXME: 0 sections... as header.NumberOfSections */
|
||||
check_write_file(hfile, &debug_dir, sizeof(debug_dir));
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == debug_dir.PointerToRawData, "mismatch\n");
|
||||
if (blob)
|
||||
{
|
||||
where = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
|
||||
blob->debug_directory.PointerToRawData = (blob->debug_directory.SizeOfData) ?
|
||||
where + sizeof(IMAGE_DEBUG_DIRECTORY) : 0;
|
||||
check_write_file(hfile, &blob->debug_directory, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
check_write_file(hfile, blob->content, blob->debug_directory.SizeOfData);
|
||||
}
|
||||
expected_size = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
||||
if (blob)
|
||||
expected_size += sizeof(IMAGE_DEBUG_DIRECTORY) + blob->debug_directory.SizeOfData;
|
||||
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == expected_size, "Incorrect file length\n");
|
||||
|
||||
CloseHandle(hfile);
|
||||
return TRUE;
|
||||
|
@ -725,16 +737,16 @@ static void test_srvgetindexes_pe(void)
|
|||
DWORD sig;
|
||||
WCHAR pdb_name[16];
|
||||
WCHAR dbg_name[16];
|
||||
BOOL in_error;
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
/* error cases */
|
||||
/* 0 */{0, {-1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, .in_error = TRUE},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, .in_error = TRUE}, /* not 100% logical ! */
|
||||
/* 0 */{0, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, 124, &guid1, 0, .pdb_name = L"pdbds.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT}, /* not 100% logical ! */
|
||||
/* success */
|
||||
/* 5 */{0, { 0, -1, -1}, 0, &null_guid, 0 },
|
||||
{0, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb"},
|
||||
|
@ -796,16 +808,16 @@ static void test_srvgetindexes_pe(void)
|
|||
memset(&ssii, 0xa5, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
if (indexes[i].in_error)
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have failed\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
ok(GetLastError() == indexes[i].last_error, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
if (ret || indexes[i].last_error == ERROR_BAD_EXE_FORMAT)
|
||||
{
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lu\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
|
@ -882,48 +894,69 @@ static void test_srvgetindexes_dbg(void)
|
|||
WCHAR filename[128];
|
||||
SYMSRV_INDEX_INFOW ssii;
|
||||
BOOL ret;
|
||||
struct debug_directory_blob *blob_refs[1];
|
||||
|
||||
static struct
|
||||
{
|
||||
/* input parameters */
|
||||
WORD machine;
|
||||
DWORD characteristics;
|
||||
DWORD timestamp;
|
||||
DWORD imagesize;
|
||||
int blob;
|
||||
/* output parameters */
|
||||
DWORD age;
|
||||
const GUID *guid;
|
||||
WCHAR pdbname[16];
|
||||
WCHAR dbgname[16];
|
||||
DWORD last_error;
|
||||
}
|
||||
indexes[] =
|
||||
{
|
||||
{IMAGE_FILE_MACHINE_I386, 0x1234, 0x00560000},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0x1235, 0x00570000},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
|
||||
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
|
||||
};
|
||||
|
||||
blob_refs[0] = make_pdb_ds_blob(0x1226, &guid1, 123, "foo.pdb");
|
||||
for (i = 0; i < ARRAY_SIZE(indexes); i++)
|
||||
{
|
||||
winetest_push_context("dbg#%02u", i);
|
||||
|
||||
/* create dll */
|
||||
swprintf(filename, ARRAY_SIZE(filename), L"winetest%02u.dbg", i);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].timestamp, indexes[i].imagesize);
|
||||
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].characteristics,
|
||||
indexes[i].timestamp, indexes[i].imagesize,
|
||||
indexes[i].blob == -1 ? NULL : blob_refs[indexes[i].blob]);
|
||||
ok(ret, "Couldn't create dbg file %ls\n", filename);
|
||||
|
||||
memset(&ssii, 0x45, sizeof(ssii));
|
||||
ssii.sizeofstruct = sizeof(ssii);
|
||||
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
|
||||
if (indexes[i].last_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have\n");
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Unexpected last error: %lu\n", GetLastError());
|
||||
}
|
||||
else
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
ok(ssii.age == 0, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(!memcmp(&ssii.guid, &null_guid, sizeof(GUID)),
|
||||
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
|
||||
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
|
||||
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
|
||||
|
||||
ok(ssii.sig == 0, "Mismatch in sig: %lx\n", ssii.sig);
|
||||
ok(ssii.size == indexes[i].imagesize, "Mismatch in size: %lx\n", ssii.size);
|
||||
ok(!ssii.stripped, "Mismatch in stripped: %x\n", ssii.stripped);
|
||||
ok(ssii.timestamp == indexes[i].timestamp, "Mismatch in timestamp: %lx\n", ssii.timestamp);
|
||||
ok(!wcscmp(ssii.file, filename), "Mismatch in file: %ls\n", ssii.file);
|
||||
ok(!ssii.pdbfile[0], "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!ssii.dbgfile[0], "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
ok(!wcscmp(ssii.pdbfile, indexes[i].pdbname), "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
|
||||
ok(!wcscmp(ssii.dbgfile, indexes[i].dbgname), "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
|
||||
|
||||
DeleteFileW(filename);
|
||||
winetest_pop_context();
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(blob_refs); i++) free(blob_refs[i]);
|
||||
}
|
||||
|
||||
static void make_path(WCHAR file[MAX_PATH], const WCHAR* topdir, const WCHAR* subdir, const WCHAR* base)
|
||||
|
@ -1533,7 +1566,8 @@ static void test_load_modules_path(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
/*create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, blob); */
|
||||
ok(0, "not supported yet\n");
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
@ -1754,7 +1788,7 @@ static void test_load_modules_details(void)
|
|||
if (test_files[val].guid)
|
||||
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
|
||||
else
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
|
||||
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, NULL);
|
||||
}
|
||||
else ok(0, "Unrecognized file reference %c\n", *ptr);
|
||||
}
|
||||
|
|
|
@ -354,7 +354,7 @@ static int wait_select_reply( void *cookie )
|
|||
/***********************************************************************
|
||||
* invoke_user_apc
|
||||
*/
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status )
|
||||
static NTSTATUS invoke_user_apc( CONTEXT *context, const struct user_apc *apc, NTSTATUS status )
|
||||
{
|
||||
return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2],
|
||||
wine_server_get_ptr( apc->func ), status );
|
||||
|
@ -364,7 +364,7 @@ static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTAT
|
|||
/***********************************************************************
|
||||
* invoke_system_apc
|
||||
*/
|
||||
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
|
||||
static void invoke_system_apc( const union apc_call *call, union apc_result *result, BOOL self )
|
||||
{
|
||||
SIZE_T size, bits;
|
||||
void *addr;
|
||||
|
@ -688,19 +688,19 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
|
|||
* server_select
|
||||
*/
|
||||
unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc )
|
||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc )
|
||||
{
|
||||
unsigned int ret;
|
||||
int cookie;
|
||||
obj_handle_t apc_handle = 0;
|
||||
BOOL suspend_context = !!context;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
sigset_t old_set;
|
||||
int signaled;
|
||||
data_size_t reply_size;
|
||||
struct
|
||||
{
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
context_t context[2];
|
||||
} reply_data;
|
||||
|
||||
|
@ -768,7 +768,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
|
|||
{
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
unsigned int ret;
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
|
||||
if (abs_timeout < 0)
|
||||
{
|
||||
|
@ -794,7 +794,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
|
|||
*/
|
||||
NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
if (alertable)
|
||||
|
@ -811,7 +811,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
|
|||
*/
|
||||
NTSTATUS WINAPI NtTestAlert(void)
|
||||
{
|
||||
user_apc_t apc;
|
||||
struct user_apc apc;
|
||||
NTSTATUS status;
|
||||
|
||||
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, &apc );
|
||||
|
@ -823,7 +823,7 @@ NTSTATUS WINAPI NtTestAlert(void)
|
|||
/***********************************************************************
|
||||
* server_queue_process_apc
|
||||
*/
|
||||
unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result )
|
||||
unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call, union apc_result *result )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1759,8 +1759,8 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE
|
|||
|
||||
if ((options & DUPLICATE_CLOSE_SOURCE) && source_process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -1323,8 +1323,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -1712,7 +1712,7 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
|
|||
ULONG_PTR arg2, ULONG_PTR arg3 )
|
||||
{
|
||||
unsigned int ret;
|
||||
apc_call_t call;
|
||||
union apc_call call;
|
||||
|
||||
SERVER_START_REQ( queue_apc )
|
||||
{
|
||||
|
|
|
@ -209,11 +209,11 @@ extern unsigned int server_call_unlocked( void *req_ptr );
|
|||
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
|
||||
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc );
|
||||
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc );
|
||||
extern unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
|
||||
apc_result_t *result );
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
|
||||
union apc_result *result );
|
||||
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options );
|
||||
extern void wine_server_send_fd( int fd );
|
||||
|
@ -436,10 +436,10 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
|
|||
if (!process_exiting) pthread_mutex_unlock( mutex );
|
||||
}
|
||||
|
||||
static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
static inline struct async_data server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
|
||||
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
|
||||
{
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
async.handle = wine_server_obj_handle( handle );
|
||||
async.user = wine_server_client_ptr( user );
|
||||
async.iosb = iosb;
|
||||
|
|
|
@ -4671,8 +4671,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
unsigned int status;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
@ -4817,8 +4817,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4864,8 +4864,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -4962,8 +4962,8 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5146,8 +5146,8 @@ static unsigned int get_basic_memory_info( HANDLE process, LPCVOID addr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5559,8 +5559,8 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5596,8 +5596,8 @@ NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5672,8 +5672,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5744,8 +5744,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5788,8 +5788,8 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -5973,8 +5973,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
@ -6359,8 +6359,8 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
|
|||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
union apc_call call;
|
||||
union apc_result result;
|
||||
|
||||
memset( &call, 0, sizeof(call) );
|
||||
|
||||
|
|
|
@ -761,12 +761,20 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
|
||||
{
|
||||
HWND last_focus = x11drv_thread_data()->last_focus;
|
||||
HWND last_focus = x11drv_thread_data()->last_focus, foreground = NtUserGetForegroundWindow();
|
||||
|
||||
TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
|
||||
hwnd, NtUserIsWindowEnabled(hwnd), NtUserIsWindowVisible(hwnd),
|
||||
(int)NtUserGetWindowLongW(hwnd, GWL_STYLE),
|
||||
get_focus(), get_active_window(), NtUserGetForegroundWindow(), last_focus );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, event_time, foreground );
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p\n", hwnd, event->window,
|
||||
event->serial, event_time, foreground );
|
||||
TRACE( " enabled %u, visible %u, style %#x, focus %p, active %p, last %p\n",
|
||||
NtUserIsWindowEnabled( hwnd ), NtUserIsWindowVisible( hwnd ), (int)NtUserGetWindowLongW( hwnd, GWL_STYLE ),
|
||||
get_focus(), get_active_window(), last_focus );
|
||||
|
||||
if (can_activate_window(hwnd))
|
||||
{
|
||||
|
@ -783,7 +791,7 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
|
|||
}
|
||||
else if (hwnd == NtUserGetDesktopWindow())
|
||||
{
|
||||
hwnd = NtUserGetForegroundWindow();
|
||||
hwnd = foreground;
|
||||
if (!hwnd) hwnd = last_focus;
|
||||
if (!hwnd) hwnd = NtUserGetDesktopWindow();
|
||||
set_focus( event->display, hwnd, event_time );
|
||||
|
@ -845,14 +853,23 @@ BOOL is_current_process_focused(void)
|
|||
*/
|
||||
static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
BOOL was_grabbed;
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
if (window_has_pending_wm_state( hwnd, -1 ))
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
if (event->detail == NotifyPointer) return FALSE;
|
||||
/* when focusing in the virtual desktop window, re-apply the cursor clipping rect */
|
||||
if (is_virtual_desktop() && hwnd == NtUserGetDesktopWindow()) reapply_cursor_clipping();
|
||||
if (hwnd == NtUserGetDesktopWindow()) return FALSE;
|
||||
|
@ -921,10 +938,9 @@ static void focus_out( Display *display , HWND hwnd )
|
|||
*/
|
||||
static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
||||
{
|
||||
HWND foreground = NtUserGetForegroundWindow();
|
||||
XFocusChangeEvent *event = &xev->xfocus;
|
||||
|
||||
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
|
||||
|
||||
if (event->detail == NotifyPointer)
|
||||
{
|
||||
if (!hwnd && event->window == x11drv_thread_data()->clip_window)
|
||||
|
@ -938,6 +954,16 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
|||
}
|
||||
if (!hwnd) return FALSE;
|
||||
|
||||
if (window_has_pending_wm_state( hwnd, NormalState )) /* ignore FocusOut only if the window is being shown */
|
||||
{
|
||||
WARN( "Ignoring window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
|
||||
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE( "window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
|
||||
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
|
||||
|
||||
/* in virtual desktop mode or when keyboard is grabbed, release any cursor grab but keep the clipping rect */
|
||||
keyboard_grabbed = event->mode == NotifyGrab || event->mode == NotifyWhileGrabbed;
|
||||
if (is_virtual_desktop() || keyboard_grabbed) ungrab_clipping_window();
|
||||
|
@ -1078,8 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
POINT pos = {event->x, event->y};
|
||||
UINT style, flags = 0, config_cmd = 0;
|
||||
int cx, cy, x, y;
|
||||
UINT config_cmd;
|
||||
|
||||
if (!hwnd) return FALSE;
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
|
@ -1098,69 +1123,8 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
|
|||
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
|
||||
window_configure_notify( data, event->serial, &rect );
|
||||
|
||||
if (!data->mapped || data->iconic) goto done;
|
||||
if (!data->whole_window || !data->managed) goto done;
|
||||
if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0)
|
||||
{
|
||||
TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n",
|
||||
hwnd, data->whole_window, event->x, event->y, event->width, event->height,
|
||||
event->serial, data->configure_serial );
|
||||
goto done;
|
||||
}
|
||||
|
||||
rect = window_rect_from_visible( &data->rects, rect );
|
||||
|
||||
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
|
||||
hwnd, data->whole_window, (int)rect.left, (int)rect.top,
|
||||
(int)(rect.right-rect.left), (int)(rect.bottom-rect.top),
|
||||
event->x, event->y, event->width, event->height );
|
||||
|
||||
/* Compare what has changed */
|
||||
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
|
||||
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
|
||||
|
||||
if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE;
|
||||
else
|
||||
TRACE( "%p moving from (%d,%d) to (%d,%d)\n",
|
||||
hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
|
||||
|
||||
if ((data->rects.window.right - data->rects.window.left == cx &&
|
||||
data->rects.window.bottom - data->rects.window.top == cy) ||
|
||||
IsRectEmpty( &data->rects.window ))
|
||||
flags |= SWP_NOSIZE;
|
||||
else
|
||||
TRACE( "%p resizing from (%dx%d) to (%dx%d)\n",
|
||||
hwnd, (int)(data->rects.window.right - data->rects.window.left),
|
||||
(int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
config_cmd = SC_MAXIMIZE;
|
||||
}
|
||||
else if (!(data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
config_cmd = SC_RESTORE;
|
||||
}
|
||||
}
|
||||
if (!config_cmd && (flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
|
||||
{
|
||||
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window,
|
||||
wine_dbgstr_rect(&data->rects.window), wine_dbgstr_rect(&rect), flags );
|
||||
config_cmd = MAKELONG(SC_MOVE, flags);
|
||||
}
|
||||
done:
|
||||
config_cmd = window_update_client_config( data );
|
||||
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||
release_win_data( data );
|
||||
|
||||
if (config_cmd)
|
||||
|
@ -1232,7 +1196,7 @@ static int get_window_xembed_info( Display *display, Window window )
|
|||
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
UINT style, value = 0, state_cmd = 0;
|
||||
UINT value = 0, state_cmd = 0;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return;
|
||||
if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window );
|
||||
|
@ -1253,50 +1217,13 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
|
|||
TRACE( "%p/%lx: new WM_STATE %d from %d\n",
|
||||
data->hwnd, data->whole_window, new_state, old_state );
|
||||
data->wm_state = new_state;
|
||||
/* ignore the initial state transition out of withdrawn state */
|
||||
/* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
|
||||
if (!old_state) goto done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!update_window || !data->managed || !data->mapped) goto done;
|
||||
if (update_window) state_cmd = window_update_client_state( data );
|
||||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
if (data->iconic && data->wm_state == NormalState) /* restore window */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
|
||||
if ((style & WS_CAPTION) == WS_CAPTION && (data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
state_cmd = SC_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
BOOL activate = (style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE);
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
state_cmd = MAKELONG(SC_RESTORE, activate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
state_cmd = SC_MINIMIZE;
|
||||
}
|
||||
}
|
||||
done:
|
||||
release_win_data( data );
|
||||
|
||||
if (state_cmd)
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "ime.h"
|
||||
#include "kbd.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
|
|
@ -1160,7 +1160,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
|
|||
long monitors[4];
|
||||
XEvent xev;
|
||||
|
||||
if (!(data->net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
if (!(data->pending_state.net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|
||||
|| NtUserGetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE)
|
||||
return;
|
||||
|
||||
|
@ -1328,7 +1328,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
|
||||
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
if (style & WS_MINIMIZE)
|
||||
new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
||||
new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
|
||||
if (data->is_fullscreen)
|
||||
{
|
||||
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
|
||||
|
@ -1352,7 +1352,6 @@ static void update_net_wm_states( struct x11drv_win_data *data )
|
|||
}
|
||||
|
||||
window_set_net_wm_state( data, new_state );
|
||||
data->net_wm_state = new_state;
|
||||
update_net_wm_fullscreen_monitors( data );
|
||||
}
|
||||
|
||||
|
@ -1418,8 +1417,8 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
|
|||
|
||||
data->pending_state.wm_state = new_state;
|
||||
data->wm_state_serial = NextRequest( data->display );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial );
|
||||
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu, foreground %p\n", data->hwnd, data->whole_window,
|
||||
old_state, new_state, data->wm_state_serial, NtUserGetForegroundWindow() );
|
||||
|
||||
switch (MAKELONG(old_state, new_state))
|
||||
{
|
||||
|
@ -1490,11 +1489,87 @@ static void unmap_window( HWND hwnd )
|
|||
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->mapped = FALSE;
|
||||
data->net_wm_state = 0;
|
||||
}
|
||||
release_win_data( data );
|
||||
}
|
||||
|
||||
UINT window_update_client_state( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
|
||||
|
||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||
if (!data->mapped) return 0; /* ignore state changes on invisible windows */
|
||||
|
||||
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */
|
||||
{
|
||||
data->iconic = FALSE;
|
||||
if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
|
||||
{
|
||||
if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
}
|
||||
else if (old_style & (WS_MINIMIZE | WS_MAXIMIZE))
|
||||
{
|
||||
BOOL activate = (old_style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE);
|
||||
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return MAKELONG(SC_RESTORE, activate);
|
||||
}
|
||||
}
|
||||
else if (!data->iconic && data->current_state.wm_state == IconicState)
|
||||
{
|
||||
data->iconic = TRUE;
|
||||
if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED))
|
||||
{
|
||||
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
|
||||
return SC_MINIMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT window_update_client_config( struct x11drv_win_data *data )
|
||||
{
|
||||
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags;
|
||||
RECT rect, old_rect = data->rects.window, new_rect;
|
||||
|
||||
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
|
||||
if (!data->mapped) return 0; /* ignore config changes on invisible windows */
|
||||
if (data->iconic) return 0; /* ignore config changes on minimized windows */
|
||||
|
||||
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
|
||||
|
||||
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
|
||||
{
|
||||
if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_MAXIMIZE;
|
||||
}
|
||||
if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE))
|
||||
{
|
||||
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
|
||||
return SC_RESTORE;
|
||||
}
|
||||
}
|
||||
|
||||
flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect );
|
||||
if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE;
|
||||
else OffsetRect( &rect, old_rect.left - new_rect.left, old_rect.top - new_rect.top );
|
||||
if (rect.right == old_rect.right && rect.bottom == old_rect.bottom) flags |= SWP_NOSIZE;
|
||||
else if (IsRectEmpty( &rect )) flags |= SWP_NOSIZE;
|
||||
|
||||
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) return 0;
|
||||
|
||||
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window,
|
||||
wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags );
|
||||
return MAKELONG(SC_MOVE, flags);
|
||||
}
|
||||
|
||||
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
|
||||
{
|
||||
UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state;
|
||||
|
@ -1593,6 +1668,19 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial
|
|||
*expect_serial = 0;
|
||||
}
|
||||
|
||||
BOOL window_has_pending_wm_state( HWND hwnd, UINT state )
|
||||
{
|
||||
struct x11drv_win_data *data;
|
||||
BOOL pending;
|
||||
|
||||
if (!(data = get_win_data( hwnd ))) return FALSE;
|
||||
if (state != -1 && data->pending_state.wm_state != state) pending = FALSE;
|
||||
else pending = !!data->wm_state_serial;
|
||||
release_win_data( data );
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* make_window_embedded
|
||||
*/
|
||||
|
@ -1600,7 +1688,6 @@ void make_window_embedded( struct x11drv_win_data *data )
|
|||
{
|
||||
/* the window cannot be mapped before being embedded */
|
||||
window_set_wm_state( data, WithdrawnState );
|
||||
data->net_wm_state = 0;
|
||||
data->embedded = TRUE;
|
||||
data->managed = TRUE;
|
||||
sync_window_style( data );
|
||||
|
@ -2012,7 +2099,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
|
|||
data->whole_window = data->client_window = 0;
|
||||
data->whole_colormap = 0;
|
||||
data->wm_state = WithdrawnState;
|
||||
data->net_wm_state = 0;
|
||||
data->mapped = FALSE;
|
||||
|
||||
memset( &data->pending_state, 0, sizeof(data->pending_state) );
|
||||
|
|
|
@ -634,7 +634,6 @@ struct x11drv_win_data
|
|||
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
|
||||
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
|
||||
int wm_state; /* current value of the WM_STATE property */
|
||||
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
|
||||
Window embedder; /* window id of embedder */
|
||||
Pixmap icon_pixmap;
|
||||
Pixmap icon_mask;
|
||||
|
@ -659,9 +658,13 @@ extern void set_gl_drawable_parent( HWND hwnd, HWND parent );
|
|||
extern void destroy_gl_drawable( HWND hwnd );
|
||||
extern void destroy_vk_surface( HWND hwnd );
|
||||
|
||||
extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state );
|
||||
extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
|
||||
extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect );
|
||||
extern UINT window_update_client_state( struct x11drv_win_data *data );
|
||||
extern UINT window_update_client_config( struct x11drv_win_data *data );
|
||||
|
||||
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set );
|
||||
extern Window init_clip_window(void);
|
||||
extern void update_user_time( Time time );
|
||||
|
|
|
@ -3886,26 +3886,23 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
|
|||
}
|
||||
else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer)
|
||||
{
|
||||
time_t tmpTime;
|
||||
struct tm tmpTM;
|
||||
SYSTEMTIME *STHook;
|
||||
SYSTEMTIME st;
|
||||
|
||||
tmpTime = ConvertTimeString(lphttpHdr->lpszValue);
|
||||
|
||||
tmpTM = *gmtime(&tmpTime);
|
||||
STHook = (SYSTEMTIME *)lpBuffer;
|
||||
STHook->wDay = tmpTM.tm_mday;
|
||||
STHook->wHour = tmpTM.tm_hour;
|
||||
STHook->wMilliseconds = 0;
|
||||
STHook->wMinute = tmpTM.tm_min;
|
||||
STHook->wDayOfWeek = tmpTM.tm_wday;
|
||||
STHook->wMonth = tmpTM.tm_mon + 1;
|
||||
STHook->wSecond = tmpTM.tm_sec;
|
||||
STHook->wYear = 1900+tmpTM.tm_year;
|
||||
|
||||
TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
|
||||
STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek,
|
||||
STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds);
|
||||
if (!InternetTimeToSystemTimeW(lphttpHdr->lpszValue, &st, 0))
|
||||
{
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_HTTP_INVALID_HEADER;
|
||||
}
|
||||
if (*lpdwBufferLength < sizeof(st))
|
||||
{
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
LeaveCriticalSection( &request->headers_section );
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
TRACE(" returning time: %04u/%02u/%02u - %u - %02u:%02u:%02u.%02u\n",
|
||||
st.wYear, st.wMonth, st.wDay, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
memcpy(lpBuffer, &st, sizeof(st));
|
||||
*lpdwBufferLength = sizeof(st);
|
||||
}
|
||||
else if (lphttpHdr->lpszValue)
|
||||
{
|
||||
|
@ -4521,7 +4518,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
|
|||
/* asctime() doesn't report a timezone, but some web servers do, so accept
|
||||
* with or without GMT.
|
||||
*/
|
||||
if (*ptr && wcscmp(ptr, L"GMT"))
|
||||
if (*ptr && (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")))
|
||||
{
|
||||
ERR("unexpected timezone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4598,7 +4595,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
@ -4715,7 +4712,7 @@ static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft)
|
|||
while (iswspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (wcscmp(ptr, L"GMT"))
|
||||
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
|
||||
{
|
||||
ERR("unexpected time zone %s\n", debugstr_w(ptr));
|
||||
return FALSE;
|
||||
|
|
|
@ -2412,6 +2412,7 @@ static const char okmsg2[] =
|
|||
"Content-Length: 0\r\n"
|
||||
"Set-Cookie: one\r\n"
|
||||
"Set-Cookie: two\r\n"
|
||||
"Last-Modified: Mon, 01 Dec 2008 13:44:34 UTC\r\n"
|
||||
"\r\n";
|
||||
|
||||
static DWORD64 content_length;
|
||||
|
@ -4566,9 +4567,11 @@ static void test_head_request(int port)
|
|||
|
||||
static void test_HttpQueryInfo(int port)
|
||||
{
|
||||
static const SYSTEMTIME expect = {2008, 12, 1, 1, 13, 44, 34};
|
||||
test_request_t req;
|
||||
DWORD size, index, error;
|
||||
char buffer[1024];
|
||||
SYSTEMTIME st;
|
||||
BOOL ret;
|
||||
|
||||
open_simple_request(&req, "localhost", port, NULL, "/testD");
|
||||
|
@ -4589,9 +4592,27 @@ static void test_HttpQueryInfo(int port)
|
|||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(buffer);
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
|
||||
size = 0;
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st) + 1;
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
size = sizeof(st);
|
||||
memset(&st, 0, sizeof(st));
|
||||
ret = HttpQueryInfoA(req.request, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
|
||||
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
|
||||
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
|
||||
ok(size == sizeof(st), "got %lu\n", size);
|
||||
ok(index == 1, "expected 1 got %lu\n", index);
|
||||
|
||||
index = 0;
|
||||
|
|
|
@ -1116,9 +1116,11 @@ static void test_InternetTimeToSystemTime(void)
|
|||
test_data[] =
|
||||
{
|
||||
{ "Fri, 07 Jan 2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "Fri, 07 Jan 2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ " fri, 7 jan 2005 12 06 35", &expect1, TRUE },
|
||||
{ "Fri, 07-01-2005 12:06:35", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 UTC", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT;", &expect1, TRUE },
|
||||
{ "5, 07-01-2005 12:06:35 GMT123", &expect1, TRUE },
|
||||
{ "2, 11 01 2022 11 13 05", &expect2, TRUE },
|
||||
|
@ -1126,6 +1128,9 @@ static void test_InternetTimeToSystemTime(void)
|
|||
{ "2, 11*01/2022 11+13=05", &expect2, TRUE },
|
||||
{ "2, 11-Jan-2022 11:13:05", &expect2, TRUE },
|
||||
{ "Fr", NULL, FALSE },
|
||||
{ "Fri Jan 7 12:06:35 2005", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 GMT", &expect1, TRUE, TRUE },
|
||||
{ "Fri Jan 7 12:06:35 2005 UTC", &expect1, TRUE, TRUE },
|
||||
};
|
||||
|
||||
ret = pInternetTimeToSystemTimeA(NULL, NULL, 0);
|
||||
|
|
|
@ -39,92 +39,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||
|
||||
#define TIME_STRING_LEN 30
|
||||
|
||||
time_t ConvertTimeString(LPCWSTR asctime)
|
||||
{
|
||||
WCHAR tmpChar[TIME_STRING_LEN];
|
||||
WCHAR *tmpChar2;
|
||||
struct tm t;
|
||||
int timelen = lstrlenW(asctime);
|
||||
|
||||
if(!timelen)
|
||||
return 0;
|
||||
|
||||
/* FIXME: the atoiWs below rely on that tmpChar is \0 padded */
|
||||
memset( tmpChar, 0, sizeof(tmpChar) );
|
||||
lstrcpynW(tmpChar, asctime, TIME_STRING_LEN);
|
||||
|
||||
/* Assert that the string is the expected length */
|
||||
if (lstrlenW(asctime) >= TIME_STRING_LEN) FIXME("\n");
|
||||
|
||||
/* Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
|
||||
* We assume the time is in this format
|
||||
* and divide it into easy to swallow chunks
|
||||
*/
|
||||
tmpChar[3]='\0';
|
||||
tmpChar[7]='\0';
|
||||
tmpChar[11]='\0';
|
||||
tmpChar[16]='\0';
|
||||
tmpChar[19]='\0';
|
||||
tmpChar[22]='\0';
|
||||
tmpChar[25]='\0';
|
||||
|
||||
memset( &t, 0, sizeof(t) );
|
||||
t.tm_year = wcstol(tmpChar+12, NULL, 10) - 1900;
|
||||
t.tm_mday = wcstol(tmpChar+5, NULL, 10);
|
||||
t.tm_hour = wcstol(tmpChar+17, NULL, 10);
|
||||
t.tm_min = wcstol(tmpChar+20, NULL, 10);
|
||||
t.tm_sec = wcstol(tmpChar+23, NULL, 10);
|
||||
|
||||
/* and month */
|
||||
tmpChar2 = tmpChar + 8;
|
||||
switch(tmpChar2[2])
|
||||
{
|
||||
case 'n':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 0;
|
||||
else
|
||||
t.tm_mon = 5;
|
||||
break;
|
||||
case 'b':
|
||||
t.tm_mon = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if(tmpChar2[1]=='a')
|
||||
t.tm_mon = 2;
|
||||
else
|
||||
t.tm_mon = 3;
|
||||
break;
|
||||
case 'y':
|
||||
t.tm_mon = 4;
|
||||
break;
|
||||
case 'l':
|
||||
t.tm_mon = 6;
|
||||
break;
|
||||
case 'g':
|
||||
t.tm_mon = 7;
|
||||
break;
|
||||
case 'p':
|
||||
t.tm_mon = 8;
|
||||
break;
|
||||
case 't':
|
||||
t.tm_mon = 9;
|
||||
break;
|
||||
case 'v':
|
||||
t.tm_mon = 10;
|
||||
break;
|
||||
case 'c':
|
||||
t.tm_mon = 11;
|
||||
break;
|
||||
default:
|
||||
FIXME("\n");
|
||||
}
|
||||
|
||||
return mktime(&t);
|
||||
}
|
||||
|
||||
|
||||
BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str)
|
||||
{
|
||||
ADDRINFOW *res, hints;
|
||||
|
|
|
@ -343,4 +343,19 @@ typedef struct tagKbdLayer
|
|||
#error "Unsupported KBD_TYPE"
|
||||
#endif
|
||||
|
||||
#define VK_DBE_ALPHANUMERIC 0x0f0
|
||||
#define VK_DBE_KATAKANA 0x0f1
|
||||
#define VK_DBE_HIRAGANA 0x0f2
|
||||
#define VK_DBE_SBCSCHAR 0x0f3
|
||||
#define VK_DBE_DBCSCHAR 0x0f4
|
||||
#define VK_DBE_ROMAN 0x0f5
|
||||
#define VK_DBE_NOROMAN 0x0f6
|
||||
#define VK_DBE_ENTERWORDREGISTERMODE 0x0f7
|
||||
#define VK_DBE_ENTERIMECONFIGMODE 0x0f8
|
||||
#define VK_DBE_FLUSHSTRING 0x0f9
|
||||
#define VK_DBE_CODEINPUT 0x0fa
|
||||
#define VK_DBE_NOCODEINPUT 0x0fb
|
||||
#define VK_DBE_DETERMINESTRING 0x0fc
|
||||
#define VK_DBE_ENTERDLGCONVERSIONMODE 0x0fd
|
||||
|
||||
#endif /* __WINE_KBD_H */
|
||||
|
|
|
@ -430,6 +430,36 @@ library UIAutomationClient {
|
|||
const long UIA_AppBarControlTypeId = 50040;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_AnnotationTypes
|
||||
{
|
||||
const long AnnotationType_Unknown = 60000;
|
||||
const long AnnotationType_SpellingError = 60001;
|
||||
const long AnnotationType_GrammarError = 60002;
|
||||
const long AnnotationType_Comment = 60003;
|
||||
const long AnnotationType_FormulaError = 60004;
|
||||
const long AnnotationType_TrackChanges = 60005;
|
||||
const long AnnotationType_Header = 60006;
|
||||
const long AnnotationType_Footer = 60007;
|
||||
const long AnnotationType_Highlighted = 60008;
|
||||
const long AnnotationType_Endnote = 60009;
|
||||
const long AnnotationType_Footnote = 60010;
|
||||
const long AnnotationType_InsertionChange = 60011;
|
||||
const long AnnotationType_DeletionChange = 60012;
|
||||
const long AnnotationType_MoveChange = 60013;
|
||||
const long AnnotationType_FormatChange = 60014;
|
||||
const long AnnotationType_UnsyncedChange = 60015;
|
||||
const long AnnotationType_EditingLockedChange = 60016;
|
||||
const long AnnotationType_ExternalChange = 60017;
|
||||
const long AnnotationType_ConflictingChange = 60018;
|
||||
const long AnnotationType_Author = 60019;
|
||||
const long AnnotationType_AdvancedProofingIssue = 60020;
|
||||
const long AnnotationType_DataValidationError = 60021;
|
||||
const long AnnotationType_CircularReferenceError = 60022;
|
||||
const long AnnotationType_Mathematics = 60023;
|
||||
const long AnnotationType_Sensitive = 60024;
|
||||
}
|
||||
|
||||
[dllname("<no entry points>")]
|
||||
module UIA_LandmarkTypeIds
|
||||
{
|
||||
|
|
42
include/wine/server_protocol.h
generated
42
include/wine/server_protocol.h
generated
|
@ -260,7 +260,7 @@ typedef struct
|
|||
} rectangle_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
struct async_data
|
||||
{
|
||||
obj_handle_t handle;
|
||||
obj_handle_t event;
|
||||
|
@ -268,7 +268,7 @@ typedef struct
|
|||
client_ptr_t user;
|
||||
client_ptr_t apc;
|
||||
apc_param_t apc_context;
|
||||
} async_data_t;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -488,18 +488,18 @@ enum apc_type
|
|||
APC_DUP_HANDLE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct user_apc
|
||||
{
|
||||
enum apc_type type;
|
||||
int __pad;
|
||||
client_ptr_t func;
|
||||
apc_param_t args[3];
|
||||
} user_apc_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_call
|
||||
{
|
||||
enum apc_type type;
|
||||
user_apc_t user;
|
||||
struct user_apc user;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
|
@ -620,9 +620,9 @@ typedef union
|
|||
unsigned int attributes;
|
||||
unsigned int options;
|
||||
} dup_handle;
|
||||
} apc_call_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_result
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
|
@ -732,7 +732,7 @@ typedef union
|
|||
enum apc_type type;
|
||||
unsigned int status;
|
||||
} break_process;
|
||||
} apc_result_t;
|
||||
};
|
||||
|
||||
enum irp_type
|
||||
{
|
||||
|
@ -1343,7 +1343,7 @@ struct get_apc_result_request
|
|||
struct get_apc_result_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
apc_result_t result;
|
||||
union apc_result result;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1829,7 +1829,7 @@ struct flush_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct flush_reply
|
||||
{
|
||||
|
@ -1857,7 +1857,7 @@ struct get_volume_info_request
|
|||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
unsigned int info_class;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1906,7 +1906,7 @@ struct recv_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int oob;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int force_async;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -1925,7 +1925,7 @@ struct send_socket_request
|
|||
{
|
||||
struct request_header __header;
|
||||
unsigned int flags;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct send_socket_reply
|
||||
{
|
||||
|
@ -2016,7 +2016,7 @@ struct read_directory_changes_request
|
|||
unsigned int filter;
|
||||
int subtree;
|
||||
int want_data;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
};
|
||||
struct read_directory_changes_reply
|
||||
{
|
||||
|
@ -3152,7 +3152,7 @@ struct register_async_request
|
|||
{
|
||||
struct request_header __header;
|
||||
int type;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
int count;
|
||||
char __pad_60[4];
|
||||
};
|
||||
|
@ -3216,7 +3216,7 @@ struct read_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
};
|
||||
struct read_reply
|
||||
|
@ -3233,7 +3233,7 @@ struct write_request
|
|||
{
|
||||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
file_pos_t pos;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
@ -3252,7 +3252,7 @@ struct ioctl_request
|
|||
{
|
||||
struct request_header __header;
|
||||
ioctl_code_t code;
|
||||
async_data_t async;
|
||||
struct async_data async;
|
||||
/* VARARG(in_data,bytes); */
|
||||
};
|
||||
struct ioctl_reply
|
||||
|
@ -6758,10 +6758,6 @@ union generic_reply
|
|||
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
|
||||
};
|
||||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 848
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -45,7 +45,7 @@ struct async
|
|||
struct timeout_user *timeout;
|
||||
unsigned int timeout_status; /* status to report upon timeout */
|
||||
struct event *event;
|
||||
async_data_t data; /* data for async I/O call */
|
||||
struct async_data data; /* data for async I/O call */
|
||||
struct iosb *iosb; /* I/O status block */
|
||||
obj_handle_t wait_handle; /* pre-allocated wait handle */
|
||||
unsigned int initial_status; /* status returned from initial request */
|
||||
|
@ -180,7 +180,7 @@ void async_terminate( struct async *async, unsigned int status )
|
|||
|
||||
if (!async->direct_result)
|
||||
{
|
||||
apc_call_t data;
|
||||
union apc_call data;
|
||||
|
||||
memset( &data, 0, sizeof(data) );
|
||||
data.type = APC_ASYNC_IO;
|
||||
|
@ -248,7 +248,7 @@ void queue_async( struct async_queue *queue, struct async *async )
|
|||
}
|
||||
|
||||
/* create an async on a given queue of a fd */
|
||||
struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb )
|
||||
struct async *create_async( struct fd *fd, struct thread *thread, const struct async_data *data, struct iosb *iosb )
|
||||
{
|
||||
struct event *event = NULL;
|
||||
struct async *async;
|
||||
|
@ -515,7 +515,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
|||
{
|
||||
if (async->data.apc)
|
||||
{
|
||||
apc_call_t data;
|
||||
union apc_call data;
|
||||
memset( &data, 0, sizeof(data) );
|
||||
data.type = APC_USER;
|
||||
data.user.func = async->data.apc;
|
||||
|
@ -753,7 +753,7 @@ static struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_
|
|||
|
||||
/* create an async associated with iosb for async-based requests
|
||||
* returned async must be passed to async_handoff */
|
||||
struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data, int is_system )
|
||||
struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const struct async_data *data, int is_system )
|
||||
{
|
||||
struct async *async;
|
||||
struct iosb *iosb;
|
||||
|
|
|
@ -252,8 +252,8 @@ extern struct object *create_serial( struct fd *fd );
|
|||
typedef void (*async_completion_callback)( void *private );
|
||||
|
||||
extern void free_async_queue( struct async_queue *queue );
|
||||
extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
|
||||
extern struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data,
|
||||
extern struct async *create_async( struct fd *fd, struct thread *thread, const struct async_data *data, struct iosb *iosb );
|
||||
extern struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const struct async_data *data,
|
||||
int is_system );
|
||||
extern obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_blocking );
|
||||
extern void queue_async( struct async_queue *queue, struct async *async );
|
||||
|
|
|
@ -262,6 +262,9 @@ void init_memory(void)
|
|||
page_mask = sysconf( _SC_PAGESIZE ) - 1;
|
||||
free_map_addr( 0x60000000, 0x1c000000 );
|
||||
free_map_addr( 0x600000000000, 0x100000000000 );
|
||||
if (page_mask != 0xfff)
|
||||
fprintf( stderr, "wineserver: page size is %uk but Wine requires 4k pages, expect problems\n",
|
||||
(int)(page_mask + 1) / 1024 );
|
||||
}
|
||||
|
||||
static void ranges_dump( struct object *obj, int verbose )
|
||||
|
|
|
@ -276,7 +276,7 @@ typedef struct
|
|||
} rectangle_t;
|
||||
|
||||
/* structure for parameters of async I/O calls */
|
||||
typedef struct
|
||||
struct async_data
|
||||
{
|
||||
obj_handle_t handle; /* object to perform I/O on */
|
||||
obj_handle_t event; /* event to signal when done */
|
||||
|
@ -284,7 +284,7 @@ typedef struct
|
|||
client_ptr_t user; /* opaque user data containing callback pointer and async-specific data */
|
||||
client_ptr_t apc; /* user APC to call */
|
||||
apc_param_t apc_context; /* user APC context or completion value */
|
||||
} async_data_t;
|
||||
};
|
||||
|
||||
/* structures for extra message data */
|
||||
|
||||
|
@ -504,18 +504,18 @@ enum apc_type
|
|||
APC_DUP_HANDLE
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct user_apc
|
||||
{
|
||||
enum apc_type type; /* APC_USER */
|
||||
int __pad;
|
||||
client_ptr_t func; /* void (__stdcall *func)(ULONG_PTR,ULONG_PTR,ULONG_PTR); */
|
||||
apc_param_t args[3]; /* arguments for user function */
|
||||
} user_apc_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_call
|
||||
{
|
||||
enum apc_type type;
|
||||
user_apc_t user;
|
||||
struct user_apc user;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_ASYNC_IO */
|
||||
|
@ -636,9 +636,9 @@ typedef union
|
|||
unsigned int attributes; /* object attributes */
|
||||
unsigned int options; /* duplicate options */
|
||||
} dup_handle;
|
||||
} apc_call_t;
|
||||
};
|
||||
|
||||
typedef union
|
||||
union apc_result
|
||||
{
|
||||
enum apc_type type;
|
||||
struct
|
||||
|
@ -748,7 +748,7 @@ typedef union
|
|||
enum apc_type type; /* APC_BREAK_PROCESS */
|
||||
unsigned int status; /* status returned by call */
|
||||
} break_process;
|
||||
} apc_result_t;
|
||||
};
|
||||
|
||||
enum irp_type
|
||||
{
|
||||
|
@ -1232,7 +1232,7 @@ typedef struct
|
|||
@REQ(get_apc_result)
|
||||
obj_handle_t handle; /* handle to the APC */
|
||||
@REPLY
|
||||
apc_result_t result; /* result of the APC */
|
||||
union apc_result result; /* result of the APC */
|
||||
@END
|
||||
|
||||
|
||||
|
@ -1539,7 +1539,7 @@ enum server_fd_type
|
|||
|
||||
/* Flush a file buffers */
|
||||
@REQ(flush)
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
@REPLY
|
||||
obj_handle_t event; /* event set when finished */
|
||||
@END
|
||||
|
@ -1555,7 +1555,7 @@ enum server_fd_type
|
|||
/* Query volume information */
|
||||
@REQ(get_volume_info)
|
||||
obj_handle_t handle; /* handle to the file */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
unsigned int info_class; /* queried information class */
|
||||
@REPLY
|
||||
obj_handle_t wait; /* handle to wait on for blocking read */
|
||||
|
@ -1586,7 +1586,7 @@ enum server_fd_type
|
|||
/* Perform a recv on a socket */
|
||||
@REQ(recv_socket)
|
||||
int oob; /* are we receiving OOB data? */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
int force_async; /* Force asynchronous mode? */
|
||||
@REPLY
|
||||
obj_handle_t wait; /* handle to wait on for blocking recv */
|
||||
|
@ -1598,7 +1598,7 @@ enum server_fd_type
|
|||
/* Perform a send on a socket */
|
||||
@REQ(send_socket)
|
||||
unsigned int flags; /* SERVER_SOCKET_IO_* flags */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
@REPLY
|
||||
obj_handle_t wait; /* handle to wait on for blocking send */
|
||||
unsigned int options; /* device open options */
|
||||
|
@ -1656,7 +1656,7 @@ enum server_fd_type
|
|||
unsigned int filter; /* notification filter */
|
||||
int subtree; /* watch the subtree? */
|
||||
int want_data; /* flag indicating whether change data should be collected */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
@END
|
||||
|
||||
|
||||
|
@ -2355,7 +2355,7 @@ enum message_type
|
|||
/* Create an async I/O */
|
||||
@REQ(register_async)
|
||||
int type; /* type of queue to look after */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
int count; /* count - usually # of bytes to be read/written */
|
||||
@END
|
||||
#define ASYNC_TYPE_READ 0x01
|
||||
|
@ -2392,7 +2392,7 @@ enum message_type
|
|||
|
||||
/* Perform a read on a file object */
|
||||
@REQ(read)
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
file_pos_t pos; /* read position */
|
||||
@REPLY
|
||||
obj_handle_t wait; /* handle to wait on for blocking read */
|
||||
|
@ -2403,7 +2403,7 @@ enum message_type
|
|||
|
||||
/* Perform a write on a file object */
|
||||
@REQ(write)
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
file_pos_t pos; /* write position */
|
||||
VARARG(data,bytes); /* write data */
|
||||
@REPLY
|
||||
|
@ -2416,7 +2416,7 @@ enum message_type
|
|||
/* Perform an ioctl on a file */
|
||||
@REQ(ioctl)
|
||||
ioctl_code_t code; /* ioctl code */
|
||||
async_data_t async; /* async I/O parameters */
|
||||
struct async_data async; /* async I/O parameters */
|
||||
VARARG(in_data,bytes); /* ioctl input data */
|
||||
@REPLY
|
||||
obj_handle_t wait; /* handle to wait on for blocking ioctl */
|
||||
|
|
|
@ -60,8 +60,7 @@
|
|||
#include "thread.h"
|
||||
#include "security.h"
|
||||
#include "handle.h"
|
||||
#define WANT_REQUEST_HANDLERS
|
||||
#include "request.h"
|
||||
#include "request_handlers.h"
|
||||
|
||||
/* Some versions of glibc don't define this */
|
||||
#ifndef SCM_RIGHTS
|
||||
|
|
2266
server/request.h
2266
server/request.h
File diff suppressed because it is too large
Load diff
2264
server/request_handlers.h
generated
Normal file
2264
server/request_handlers.h
generated
Normal file
File diff suppressed because it is too large
Load diff
4399
server/request_trace.h
generated
Normal file
4399
server/request_trace.h
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -79,8 +79,8 @@ struct thread_apc
|
|||
struct thread *caller; /* thread that queued this apc */
|
||||
struct object *owner; /* object that queued this apc */
|
||||
int executed; /* has it been executed by the client? */
|
||||
apc_call_t call; /* call arguments */
|
||||
apc_result_t result; /* call results once executed */
|
||||
union apc_call call; /* call arguments */
|
||||
union apc_result result; /* call results once executed */
|
||||
};
|
||||
|
||||
static void dump_thread_apc( struct object *obj, int verbose );
|
||||
|
@ -508,7 +508,7 @@ static void thread_apc_destroy( struct object *obj )
|
|||
}
|
||||
|
||||
/* queue an async procedure call */
|
||||
static struct thread_apc *create_apc( struct object *owner, const apc_call_t *call_data )
|
||||
static struct thread_apc *create_apc( struct object *owner, const union apc_call *call_data )
|
||||
{
|
||||
struct thread_apc *apc;
|
||||
|
||||
|
@ -1155,7 +1155,7 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr
|
|||
}
|
||||
|
||||
/* queue an async procedure call */
|
||||
int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data )
|
||||
int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const union apc_call *call_data )
|
||||
{
|
||||
struct thread_apc *apc;
|
||||
int ret = 0;
|
||||
|
@ -1584,7 +1584,7 @@ DECL_HANDLER(select)
|
|||
data_size_t op_size, ctx_size;
|
||||
struct context *ctx;
|
||||
struct thread_apc *apc;
|
||||
const apc_result_t *result = get_req_data();
|
||||
const union apc_result *result = get_req_data();
|
||||
unsigned int ctx_count;
|
||||
|
||||
if (get_req_data_size() < sizeof(*result)) goto invalid_param;
|
||||
|
@ -1665,13 +1665,13 @@ DECL_HANDLER(select)
|
|||
|
||||
reply->signaled = select_on( &select_op, op_size, req->cookie, req->flags, req->timeout );
|
||||
|
||||
if (get_error() == STATUS_USER_APC && get_reply_max_size() >= sizeof(apc_call_t))
|
||||
if (get_error() == STATUS_USER_APC && get_reply_max_size() >= sizeof(union apc_call))
|
||||
{
|
||||
apc = thread_dequeue_apc( current, 0 );
|
||||
set_reply_data( &apc->call, sizeof(apc->call) );
|
||||
release_object( apc );
|
||||
}
|
||||
else if (get_error() == STATUS_KERNEL_APC && get_reply_max_size() >= sizeof(apc_call_t))
|
||||
else if (get_error() == STATUS_KERNEL_APC && get_reply_max_size() >= sizeof(union apc_call))
|
||||
{
|
||||
apc = thread_dequeue_apc( current, 1 );
|
||||
if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 )))
|
||||
|
@ -1685,13 +1685,13 @@ DECL_HANDLER(select)
|
|||
}
|
||||
release_object( apc );
|
||||
}
|
||||
else if (reply->signaled && get_reply_max_size() >= sizeof(apc_call_t) + sizeof(context_t) &&
|
||||
else if (reply->signaled && get_reply_max_size() >= sizeof(union apc_call) + sizeof(context_t) &&
|
||||
current->context && current->suspend_cookie == req->cookie)
|
||||
{
|
||||
ctx = current->context;
|
||||
if (ctx->regs[CTX_NATIVE].flags || ctx->regs[CTX_WOW].flags)
|
||||
{
|
||||
apc_call_t *data;
|
||||
union apc_call *data;
|
||||
data_size_t size = sizeof(*data) + (ctx->regs[CTX_WOW].flags ? 2 : 1) * sizeof(context_t);
|
||||
unsigned int flags = system_flags & ctx->regs[CTX_NATIVE].flags;
|
||||
|
||||
|
@ -1718,7 +1718,7 @@ DECL_HANDLER(queue_apc)
|
|||
struct thread *thread = NULL;
|
||||
struct process *process = NULL;
|
||||
struct thread_apc *apc;
|
||||
const apc_call_t *call = get_req_data();
|
||||
const union apc_call *call = get_req_data();
|
||||
|
||||
if (get_req_data_size() < sizeof(*call)) call = NULL;
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
|
|||
extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
|
||||
extern void kill_thread( struct thread *thread, int violent_death );
|
||||
extern void wake_up( struct object *obj, int max );
|
||||
extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const apc_call_t *call_data );
|
||||
extern int thread_queue_apc( struct process *process, struct thread *thread, struct object *owner, const union apc_call *call_data );
|
||||
extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type );
|
||||
extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
|
||||
extern int thread_get_inflight_fd( struct thread *thread, int client );
|
||||
|
|
|
@ -123,7 +123,7 @@ static void timer_callback( void *private )
|
|||
/* queue an APC */
|
||||
if (timer->thread)
|
||||
{
|
||||
apc_call_t data;
|
||||
union apc_call data;
|
||||
|
||||
assert (timer->callback);
|
||||
memset( &data, 0, sizeof(data) );
|
||||
|
|
4389
server/trace.c
4389
server/trace.c
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
#! /usr/bin/perl -w
|
||||
#
|
||||
# Build the server/trace.c and server/request.h files
|
||||
# Build the server protocol definitions
|
||||
# from the contents of server/protocol.def.
|
||||
#
|
||||
# Copyright (C) 1998 Alexandre Julliard
|
||||
|
@ -32,30 +32,18 @@ my %formats =
|
|||
"data_size_t" => [ 4, 4, "%u" ],
|
||||
"obj_handle_t" => [ 4, 4, "%04x" ],
|
||||
"atom_t" => [ 4, 4, "%04x" ],
|
||||
"user_handle_t" => [ 4, 4, "%08x" ],
|
||||
"process_id_t" => [ 4, 4, "%04x" ],
|
||||
"thread_id_t" => [ 4, 4, "%04x" ],
|
||||
"client_ptr_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"mod_handle_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"lparam_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"apc_param_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"file_pos_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"mem_size_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"affinity_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"object_id_t" => [ 8, 8, "&dump_uint64" ],
|
||||
"timeout_t" => [ 8, 8, "&dump_timeout" ],
|
||||
"abstime_t" => [ 8, 8, "&dump_abstime" ],
|
||||
"rectangle_t" => [ 16, 4, "&dump_rectangle" ],
|
||||
"apc_result_t" => [ 40, 8, "&dump_apc_result" ],
|
||||
"async_data_t" => [ 40, 8, "&dump_async_data" ],
|
||||
"irp_params_t" => [ 32, 8, "&dump_irp_params" ],
|
||||
"struct luid" => [ 8, 4, "&dump_luid" ],
|
||||
"generic_map_t" => [ 16, 4, "&dump_generic_map" ],
|
||||
"ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ],
|
||||
"hw_input_t" => [ 40, 8, "&dump_hw_input" ],
|
||||
"obj_locator_t" => [ 16, 8, "&dump_obj_locator" ],
|
||||
"unsigned __int64" => [ 8, 8, "&uint64" ],
|
||||
"timeout_t" => [ 8, 8 ],
|
||||
"abstime_t" => [ 8, 8 ],
|
||||
"rectangle_t" => [ 16, 4 ],
|
||||
"irp_params_t" => [ 32, 8 ],
|
||||
"generic_map_t" => [ 16, 4 ],
|
||||
"ioctl_code_t" => [ 4, 4 ],
|
||||
"hw_input_t" => [ 40, 8 ],
|
||||
"obj_locator_t" => [ 16, 8 ],
|
||||
# varargs-only structures
|
||||
"apc_call_t" => [ 64, 8 ],
|
||||
"context_t" => [ 1728, 8 ],
|
||||
"cursor_pos_t" => [ 24, 8 ],
|
||||
"debug_event_t" => [ 160, 8 ],
|
||||
|
@ -66,21 +54,33 @@ my %formats =
|
|||
"startup_info_t" => [ 96, 4 ],
|
||||
"tcp_connection" => [ 60, 4 ],
|
||||
"udp_endpoint" => [ 32, 4 ],
|
||||
"user_apc_t" => [ 40, 8 ],
|
||||
"union apc_call" => [ 64, 8 ],
|
||||
"union apc_result" => [ 40, 8 ],
|
||||
"struct async_data" => [ 40, 8 ],
|
||||
"struct filesystem_event" => [ 12, 4 ],
|
||||
"struct handle_info" => [ 20, 4 ],
|
||||
"struct luid" => [ 8, 4 ],
|
||||
"struct luid_attr" => [ 12, 4 ],
|
||||
"struct object_attributes" => [ 16, 4 ],
|
||||
"struct object_type_info" => [ 44, 4 ],
|
||||
"struct process_info" => [ 40, 8 ],
|
||||
"struct rawinput_device" => [ 12, 4 ],
|
||||
"struct thread_info" => [ 40, 8 ],
|
||||
"struct user_apc" => [ 40, 8 ],
|
||||
);
|
||||
|
||||
my $file_header =
|
||||
"/*\n * Wine server protocol definitions\n *\n" .
|
||||
" * This file is automatically generated; DO NO EDIT!\n" .
|
||||
" * Edit server/protocol.def instead and re-run tools/make_requests\n" .
|
||||
" */\n\n";
|
||||
|
||||
my @requests = ();
|
||||
my %replies = ();
|
||||
my %dump_funcs = ();
|
||||
my @asserts = ();
|
||||
|
||||
my @protocol_lines = ();
|
||||
my @trace_lines = ();
|
||||
|
||||
my $max_req_size = 64;
|
||||
|
@ -93,7 +93,7 @@ sub add_padding($$)
|
|||
if ($offset % $padding)
|
||||
{
|
||||
my $count = $padding - ($offset % $padding);
|
||||
print SERVER_PROT " char __pad_$offset\[$count\];\n";
|
||||
push @protocol_lines, " char __pad_$offset\[$count\];\n";
|
||||
$offset += $count;
|
||||
}
|
||||
return $offset;
|
||||
|
@ -115,10 +115,24 @@ sub DO_DUMP_FUNC($$@)
|
|||
if (defined($formats{$type}))
|
||||
{
|
||||
my $fmt = ${$formats{$type}}[2];
|
||||
if ($fmt =~ /^&(.*)/)
|
||||
while ($fmt && $fmt !~ /^[%&]/)
|
||||
{
|
||||
$type = $fmt;
|
||||
$fmt = ${$formats{$type}}[2];
|
||||
}
|
||||
if (!$fmt)
|
||||
{
|
||||
my $func = $type;
|
||||
$func =~ s/^(struct|union)\s+//;
|
||||
$func =~ s/_t$//;
|
||||
push @trace_lines, " dump_$func( \"$prefix$var=\", &req->$var );\n";
|
||||
$dump_funcs{$func} = $type;
|
||||
}
|
||||
elsif ($fmt =~ /^&(.*)/)
|
||||
{
|
||||
my $func = $1;
|
||||
push @trace_lines, " $func( \"$prefix$var=\", &req->$var );\n";
|
||||
push @trace_lines, " dump_$func( \"$prefix$var=\", &req->$var );\n";
|
||||
$dump_funcs{$func} = $type;
|
||||
}
|
||||
elsif ($fmt =~ /^(%.*)\s+\((.*)\)/)
|
||||
{
|
||||
|
@ -178,8 +192,8 @@ sub PARSE_REQUESTS()
|
|||
@in_struct = ();
|
||||
@out_struct = ();
|
||||
$offset = 12;
|
||||
print SERVER_PROT "struct ${name}_request\n{\n";
|
||||
print SERVER_PROT " struct request_header __header;\n";
|
||||
push @protocol_lines, "struct ${name}_request\n{\n";
|
||||
push @protocol_lines, " struct request_header __header;\n";
|
||||
$state++;
|
||||
next;
|
||||
}
|
||||
|
@ -190,9 +204,9 @@ sub PARSE_REQUESTS()
|
|||
$offset = add_padding( $offset, 8 ); # all requests should be 8-byte aligned
|
||||
die "request $name too large ($offset)" if ($offset > $max_req_size);
|
||||
push @asserts, "C_ASSERT( sizeof(struct ${name}_request) == $offset );\n";
|
||||
print SERVER_PROT "};\n";
|
||||
print SERVER_PROT "struct ${name}_reply\n{\n";
|
||||
print SERVER_PROT " struct reply_header __header;\n";
|
||||
push @protocol_lines, "};\n";
|
||||
push @protocol_lines, "struct ${name}_reply\n{\n";
|
||||
push @protocol_lines, " struct reply_header __header;\n";
|
||||
$offset = 8;
|
||||
$state++;
|
||||
next;
|
||||
|
@ -203,14 +217,14 @@ sub PARSE_REQUESTS()
|
|||
die "Misplaced \@END" unless ($state == 2 || $state == 3);
|
||||
|
||||
$offset = add_padding( $offset, 8 ); # all requests should be 8-byte aligned
|
||||
print SERVER_PROT "};\n";
|
||||
push @protocol_lines, "};\n";
|
||||
if ($state == 2) # build dummy reply struct
|
||||
{
|
||||
die "request $name too large ($offset)" if ($offset > $max_req_size);
|
||||
push @asserts, "C_ASSERT( sizeof(struct ${name}_request) == $offset );\n";
|
||||
print SERVER_PROT "struct ${name}_reply\n{\n";
|
||||
print SERVER_PROT " struct reply_header __header;\n";
|
||||
print SERVER_PROT "};\n";
|
||||
push @protocol_lines, "struct ${name}_reply\n{\n";
|
||||
push @protocol_lines, " struct reply_header __header;\n";
|
||||
push @protocol_lines, "};\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -234,26 +248,22 @@ sub PARSE_REQUESTS()
|
|||
# skip empty lines (but keep them in output file)
|
||||
if (/^$/)
|
||||
{
|
||||
print SERVER_PROT "\n";
|
||||
push @protocol_lines, "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^\s*VARARG\((\w+),(\w+),(\d+)\)/)
|
||||
if (/^\s*VARARG\((\w+),(\w+),(\w+)\)/)
|
||||
{
|
||||
$var = $1;
|
||||
$type = "dump_varargs_$2( \"%s\", min(cur_size,$3) )";
|
||||
s!(VARARG\(.*\)\s*;)!/* $1 */!;
|
||||
}
|
||||
elsif (/^\s*VARARG\((\w+),(\w+),(\w+)\)/)
|
||||
{
|
||||
$var = $1;
|
||||
$type = "dump_varargs_" . $2 . "( \"%s\", min(cur_size,req->" . $3 . ") )";
|
||||
$type = "dump_varargs_$2( \"%s\", min( cur_size, req->" . $3 . " ))";
|
||||
$dump_funcs{"varargs_$2"} = $2;
|
||||
s!(VARARG\(.*\)\s*;)!/* $1 */!;
|
||||
}
|
||||
elsif (/^\s*VARARG\((\w+),(\w+)\)/)
|
||||
{
|
||||
$var = $1;
|
||||
$type = "dump_varargs_" . $2 . "( \"%s\", cur_size )";
|
||||
$type = "dump_varargs_$2( \"%s\", cur_size )";
|
||||
$dump_funcs{"varargs_$2"} = $2;
|
||||
s!(VARARG\(.*\)\s*;)!/* $1 */!;
|
||||
}
|
||||
elsif (/^\s*(\w+\**(\s+\w+\**)*)\s+(\w+);/)
|
||||
|
@ -266,16 +276,16 @@ sub PARSE_REQUESTS()
|
|||
{
|
||||
my $count = $fmt[1] - ($offset & ($fmt[1] - 1));
|
||||
print "protocol.def:$.: warning: $name $offset $type $var needs padding\n" if $warnings;
|
||||
print SERVER_PROT " char __pad_$offset\[$count\];\n";
|
||||
push @protocol_lines, " char __pad_$offset\[$count\];\n";
|
||||
$offset += $count;
|
||||
}
|
||||
if ($state == 2)
|
||||
{
|
||||
push @asserts, "C_ASSERT( FIELD_OFFSET(struct ${name}_request, $var) == $offset );\n";
|
||||
push @asserts, "C_ASSERT( offsetof(struct ${name}_request, $var) == $offset );\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
push @asserts, "C_ASSERT( FIELD_OFFSET(struct ${name}_reply, $var) == $offset );\n";
|
||||
push @asserts, "C_ASSERT( offsetof(struct ${name}_reply, $var) == $offset );\n";
|
||||
}
|
||||
$offset += $fmt[0];
|
||||
}
|
||||
|
@ -286,9 +296,18 @@ sub PARSE_REQUESTS()
|
|||
if ($state == 2) { push @in_struct, $type, $var; }
|
||||
if ($state == 3) { push @out_struct, $type, $var; }
|
||||
}
|
||||
elsif (/^typedef\s+(.*)\s+(\w+_t);$/)
|
||||
{
|
||||
if (defined $formats{$1} && !defined $formats{$2})
|
||||
{
|
||||
@{$formats{$2}} = @{$formats{$1}};
|
||||
$formats{$2}->[2] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Pass it through into the output file
|
||||
print SERVER_PROT $_ . "\n";
|
||||
push @protocol_lines, $_ . "\n";
|
||||
}
|
||||
close PROTOCOL;
|
||||
}
|
||||
|
@ -337,9 +356,15 @@ sub GET_ERROR_NAMES()
|
|||
}
|
||||
|
||||
# update a file if changed
|
||||
sub update_file($)
|
||||
sub update_file($@)
|
||||
{
|
||||
my $file = shift;
|
||||
my ($file, @lines) = @_;
|
||||
|
||||
open OUTPUT, ">$file.new" or die "Cannot create $file.new";
|
||||
print OUTPUT $file_header;
|
||||
print OUTPUT @lines;
|
||||
close OUTPUT;
|
||||
|
||||
my $ret = !(-f $file) || system "cmp $file $file.new >/dev/null";
|
||||
if (!$ret)
|
||||
{
|
||||
|
@ -353,42 +378,6 @@ sub update_file($)
|
|||
return $ret;
|
||||
}
|
||||
|
||||
# replace some lines in a file between two markers
|
||||
sub replace_in_file($$$@)
|
||||
{
|
||||
my $file = shift;
|
||||
my $start = shift;
|
||||
my $end = shift;
|
||||
|
||||
open NEW_FILE, ">$file.new" or die "cannot create $file.new";
|
||||
|
||||
if (defined($start))
|
||||
{
|
||||
open OLD_FILE, "$file" or die "cannot open $file";
|
||||
while (<OLD_FILE>)
|
||||
{
|
||||
print NEW_FILE $_;
|
||||
last if /$start/;
|
||||
}
|
||||
}
|
||||
|
||||
print NEW_FILE "\n", @_, "\n";
|
||||
|
||||
if (defined($end))
|
||||
{
|
||||
my $skip=1;
|
||||
while (<OLD_FILE>)
|
||||
{
|
||||
$skip = 0 if /$end/;
|
||||
print NEW_FILE $_ unless $skip;
|
||||
}
|
||||
}
|
||||
|
||||
close OLD_FILE if defined($start);
|
||||
close NEW_FILE;
|
||||
return update_file($file);
|
||||
}
|
||||
|
||||
### Main
|
||||
|
||||
# Get the server protocol version
|
||||
|
@ -398,13 +387,8 @@ my %errors = GET_ERROR_NAMES();
|
|||
|
||||
### Create server_protocol.h and print header
|
||||
|
||||
open SERVER_PROT, ">include/wine/server_protocol.h.new" or die "Cannot create include/wine/server_protocol.h.new";
|
||||
print SERVER_PROT "/*\n * Wine server protocol definitions\n *\n";
|
||||
print SERVER_PROT " * This file is automatically generated; DO NO EDIT!\n";
|
||||
print SERVER_PROT " * Edit server/protocol.def instead and re-run tools/make_requests\n";
|
||||
print SERVER_PROT " */\n\n";
|
||||
print SERVER_PROT "#ifndef __WINE_WINE_SERVER_PROTOCOL_H\n";
|
||||
print SERVER_PROT "#define __WINE_WINE_SERVER_PROTOCOL_H\n";
|
||||
push @protocol_lines, "#ifndef __WINE_WINE_SERVER_PROTOCOL_H\n";
|
||||
push @protocol_lines, "#define __WINE_WINE_SERVER_PROTOCOL_H\n";
|
||||
|
||||
### Parse requests to find request/reply structure definitions
|
||||
|
||||
|
@ -412,57 +396,53 @@ PARSE_REQUESTS();
|
|||
|
||||
### Build the request list and structures
|
||||
|
||||
print SERVER_PROT "\n\nenum request\n{\n";
|
||||
foreach my $req (@requests) { print SERVER_PROT " REQ_$req,\n"; }
|
||||
print SERVER_PROT " REQ_NB_REQUESTS\n};\n\n";
|
||||
push @protocol_lines, "\n\nenum request\n{\n";
|
||||
foreach my $req (@requests) { push @protocol_lines, " REQ_$req,\n"; }
|
||||
push @protocol_lines, " REQ_NB_REQUESTS\n};\n\n";
|
||||
|
||||
print SERVER_PROT "union generic_request\n{\n";
|
||||
print SERVER_PROT " struct request_max_size max_size;\n";
|
||||
print SERVER_PROT " struct request_header request_header;\n";
|
||||
foreach my $req (@requests) { print SERVER_PROT " struct ${req}_request ${req}_request;\n"; }
|
||||
print SERVER_PROT "};\n";
|
||||
push @protocol_lines, "union generic_request\n{\n";
|
||||
push @protocol_lines, " struct request_max_size max_size;\n";
|
||||
push @protocol_lines, " struct request_header request_header;\n";
|
||||
foreach my $req (@requests) { push @protocol_lines, " struct ${req}_request ${req}_request;\n"; }
|
||||
push @protocol_lines, "};\n";
|
||||
|
||||
print SERVER_PROT "union generic_reply\n{\n";
|
||||
print SERVER_PROT " struct request_max_size max_size;\n";
|
||||
print SERVER_PROT " struct reply_header reply_header;\n";
|
||||
foreach my $req (@requests) { print SERVER_PROT " struct ${req}_reply ${req}_reply;\n"; }
|
||||
print SERVER_PROT "};\n\n";
|
||||
push @protocol_lines, "union generic_reply\n{\n";
|
||||
push @protocol_lines, " struct request_max_size max_size;\n";
|
||||
push @protocol_lines, " struct reply_header reply_header;\n";
|
||||
foreach my $req (@requests) { push @protocol_lines, " struct ${req}_reply ${req}_reply;\n"; }
|
||||
push @protocol_lines, "};\n\n";
|
||||
|
||||
print SERVER_PROT "/* ### protocol_version begin ### */\n\n";
|
||||
printf SERVER_PROT "#define SERVER_PROTOCOL_VERSION %d\n\n", $protocol;
|
||||
print SERVER_PROT "/* ### protocol_version end ### */\n\n";
|
||||
print SERVER_PROT "#endif /* __WINE_WINE_SERVER_PROTOCOL_H */\n";
|
||||
push @protocol_lines, sprintf "#define SERVER_PROTOCOL_VERSION %d\n\n", $protocol;
|
||||
push @protocol_lines, "#endif /* __WINE_WINE_SERVER_PROTOCOL_H */\n";
|
||||
|
||||
open SERVER_PROT, ">include/wine/server_protocol.h.new" or die "Cannot create include/wine/server_protocol.h.new";
|
||||
print SERVER_PROT @protocol_lines;
|
||||
close SERVER_PROT;
|
||||
|
||||
if (update_file( "include/wine/server_protocol.h" ))
|
||||
if (update_file( "include/wine/server_protocol.h", @protocol_lines ))
|
||||
{
|
||||
my @version_lines = ();
|
||||
|
||||
push @version_lines, sprintf( "#define SERVER_PROTOCOL_VERSION %d\n", $protocol + 1 );
|
||||
|
||||
replace_in_file( "include/wine/server_protocol.h",
|
||||
"### protocol_version begin ###",
|
||||
"### protocol_version end ###",
|
||||
@version_lines );
|
||||
$protocol_lines[$#protocol_lines - 1] = sprintf "#define SERVER_PROTOCOL_VERSION %d\n\n", $protocol + 1;
|
||||
update_file( "include/wine/server_protocol.h", @protocol_lines );
|
||||
}
|
||||
|
||||
### Output the dumping function tables
|
||||
|
||||
push @trace_lines, "static const dump_func req_dumpers[REQ_NB_REQUESTS] = {\n";
|
||||
push @trace_lines, "typedef void (*dump_func)( const void *req );\n\n";
|
||||
push @trace_lines, "static const dump_func req_dumpers[REQ_NB_REQUESTS] =\n{\n";
|
||||
foreach my $req (@requests)
|
||||
{
|
||||
push @trace_lines, " (dump_func)dump_${req}_request,\n";
|
||||
}
|
||||
push @trace_lines, "};\n\n";
|
||||
|
||||
push @trace_lines, "static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {\n";
|
||||
push @trace_lines, "static const dump_func reply_dumpers[REQ_NB_REQUESTS] =\n{\n";
|
||||
foreach my $req (@requests)
|
||||
{
|
||||
push @trace_lines, " ", $replies{$req} ? "(dump_func)dump_${req}_reply,\n" : "NULL,\n";
|
||||
}
|
||||
push @trace_lines, "};\n\n";
|
||||
|
||||
push @trace_lines, "static const char * const req_names[REQ_NB_REQUESTS] = {\n";
|
||||
push @trace_lines, "static const char * const req_names[REQ_NB_REQUESTS] =\n{\n";
|
||||
foreach my $req (@requests)
|
||||
{
|
||||
push @trace_lines, " \"$req\",\n";
|
||||
|
@ -481,18 +461,32 @@ foreach my $err (sort keys %errors)
|
|||
push @trace_lines, " { NULL, 0 }\n";
|
||||
push @trace_lines, "};\n";
|
||||
|
||||
replace_in_file( "server/trace.c",
|
||||
"### make_requests begin ###",
|
||||
"### make_requests end ###",
|
||||
@trace_lines );
|
||||
|
||||
my @trace_header = ();
|
||||
|
||||
foreach my $func (sort keys %dump_funcs)
|
||||
{
|
||||
if ($func =~ /^varargs_/)
|
||||
{
|
||||
push @trace_header, "static void dump_$func( const char *prefix, data_size_t size );\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
push @trace_header, "static void dump_$func( const char *prefix, const $dump_funcs{$func} *val );\n";
|
||||
}
|
||||
}
|
||||
|
||||
push @trace_header, "\nstatic const void *cur_data;\n";
|
||||
push @trace_header, "static data_size_t cur_size;\n\n";
|
||||
|
||||
update_file( "server/request_trace.h", @trace_header, @trace_lines);
|
||||
|
||||
### Output the request handlers list
|
||||
|
||||
my @request_lines = ();
|
||||
my @request_lines = ( "#include \"request.h\"\n\n" );
|
||||
|
||||
foreach my $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; }
|
||||
push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n";
|
||||
push @request_lines, "typedef void (*req_handler)( const void *req, void *reply );\n";
|
||||
push @request_lines, "\ntypedef void (*req_handler)( const void *req, void *reply );\n";
|
||||
push @request_lines, "static const req_handler req_handlers[REQ_NB_REQUESTS] =\n{\n";
|
||||
foreach my $req (@requests)
|
||||
{
|
||||
|
@ -506,10 +500,5 @@ foreach my $type (sort keys %formats)
|
|||
die "$type: invalid size $size for alignment $align" if $size % $align;
|
||||
push @request_lines, "C_ASSERT( sizeof($type) == $size );\n";
|
||||
}
|
||||
push @request_lines, @asserts;
|
||||
push @request_lines, "\n#endif /* WANT_REQUEST_HANDLERS */\n";
|
||||
|
||||
replace_in_file( "server/request.h",
|
||||
"### make_requests begin ###",
|
||||
"### make_requests end ###",
|
||||
@request_lines );
|
||||
update_file( "server/request_handlers.h", @request_lines, @asserts );
|
||||
|
|
Loading…
Reference in a new issue