1 diff -urN wine-1.0/configure wine-1.0-uk/configure
2 --- wine-1.0/configure 2008-06-17 22:07:31.000000000 +0800
3 +++ wine-1.0-uk/configure 2009-08-18 16:11:13.000000000 +0800
5 # Identity of this package.
9 +PACKAGE_VERSION='1.0-uk'
10 PACKAGE_STRING='Wine 1.0'
11 PACKAGE_BUGREPORT='wine-devel@winehq.org'
13 diff -urN wine-1.0/dlls/comdlg32/cdlg_Cn.rc wine-1.0-uk/dlls/comdlg32/cdlg_Cn.rc
14 --- wine-1.0/dlls/comdlg32/cdlg_Cn.rc 2008-06-17 22:07:31.000000000 +0800
15 +++ wine-1.0-uk/dlls/comdlg32/cdlg_Cn.rc 2009-08-18 16:11:13.000000000 +0800
17 PD32_PRINTER_STATUS_POWER_SAVE "Power safe mode; "
20 +/* Unified Kernel: add for Chinese characters display */
21 +STRINGTABLE DISCARDABLE
23 + IDS_FONT_SIZE "Select a font size between %d and %d points."
24 + IDS_SAVE_BUTTON "±£´æ(&s)"
25 + IDS_SAVE_IN "±£´æÔÚ(&i)"
27 + IDS_SAVE_AS "Áí´æΪ"
28 + IDS_OPEN_FILE "´ò¿ªÎļþ"
30 #pragma code_page(default)
31 diff -urN wine-1.0/dlls/comdlg32/filedlg.c wine-1.0-uk/dlls/comdlg32/filedlg.c
32 --- wine-1.0/dlls/comdlg32/filedlg.c 2008-06-17 22:07:31.000000000 +0800
33 +++ wine-1.0-uk/dlls/comdlg32/filedlg.c 2009-08-18 16:11:13.000000000 +0800
34 @@ -3840,6 +3840,14 @@
36 BOOL win16look = FALSE;
38 +#ifdef UNIFIED_KERNEL
39 + char class_name[MAX_PATH];
40 + char app_name[] = "TApplication";
41 + GetClassNameA(ofn->hwndOwner, class_name, sizeof(class_name) );
43 + if (!lstrcmpA(class_name, app_name) && ofn->hwndOwner != GetActiveWindow())
44 + ofn->hwndOwner = GetActiveWindow();
46 TRACE("flags %08x\n", ofn->Flags);
48 /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
49 @@ -3870,6 +3878,14 @@
51 BOOL win16look = FALSE;
53 +#ifdef UNIFIED_KERNEL
54 + WCHAR class_name[MAX_PATH];
55 + WCHAR app_name[] = {'T', 'A','p','p','l','i','c','a','t','i','o','n', 0};
56 + GetClassNameW(ofn->hwndOwner, class_name, sizeof(class_name) );
58 + if (!lstrcmpW(class_name, app_name) && ofn->hwndOwner != GetActiveWindow())
59 + ofn->hwndOwner = GetActiveWindow();
61 TRACE("flags %08x\n", ofn->Flags);
63 /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */
64 @@ -3901,6 +3917,14 @@
66 BOOL win16look = FALSE;
68 +#ifdef UNIFIED_KERNEL
69 + char class_name[MAX_PATH];
70 + char app_name[] = "TApplication";
71 + GetClassNameA(ofn->hwndOwner, class_name, sizeof(class_name) );
73 + if (!lstrcmpA(class_name, app_name) && ofn->hwndOwner != GetActiveWindow())
74 + ofn->hwndOwner = GetActiveWindow();
76 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
77 win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
79 @@ -3925,6 +3949,14 @@
81 BOOL win16look = FALSE;
83 +#ifdef UNIFIED_KERNEL
84 + WCHAR class_name[MAX_PATH];
85 + WCHAR app_name[] = {'T', 'A','p','p','l','i','c','a','t','i','o','n', 0};
86 + GetClassNameW(ofn->hwndOwner, class_name, sizeof(class_name) );
88 + if (!lstrcmpW(class_name, app_name) && ofn->hwndOwner != GetActiveWindow())
89 + ofn->hwndOwner = GetActiveWindow();
91 if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE))
92 win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE;
94 diff -urN wine-1.0/dlls/gdi32/font.c wine-1.0-uk/dlls/gdi32/font.c
95 --- wine-1.0/dlls/gdi32/font.c 2008-06-17 22:07:31.000000000 +0800
96 +++ wine-1.0-uk/dlls/gdi32/font.c 2009-08-18 16:11:13.000000000 +0800
98 #include "gdi_private.h"
99 #include "wine/unicode.h"
100 #include "wine/debug.h"
101 +#ifdef UNIFIED_KERNEL
105 WINE_DEFAULT_DEBUG_CHANNEL(font);
107 @@ -1563,7 +1566,11 @@
110 if (flags & ETO_GLYPH_INDEX)
111 +#ifdef UNIFIED_KERNEL
112 + return ExtTextOutW( hdc, x, y, flags, lprect, (LPWSTR)str, count, lpDx );
114 return ExtTextOutW( hdc, x, y, flags, lprect, (LPCWSTR)str, count, lpDx );
117 p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
119 @@ -1620,8 +1627,13 @@
123 +#ifndef UNIFIED_KERNEL
124 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
125 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
127 +BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
128 + const RECT *lprect, LPWSTR str, UINT count, const INT *lpDx )
132 LPWSTR reordered_str = (LPWSTR)str;
133 @@ -1640,6 +1652,102 @@
134 DC * dc = get_dc_ptr( hdc );
137 +#ifdef UNIFIED_KERNEL
141 + UINT prev_align = align;
144 + if (!dc) return FALSE;
146 + if ((INT)count == -1)
147 + count = strlenW(str);
149 + if (align == TA_BASELINE) {
153 + GetTextMetricsW(hdc, &tmw);
155 + lfCloneFromDC(dc, &lf);
156 + arc = lf.lfOrientation * M_PI / 1800;
158 + x -= sin(arc) * tmw.tmAscent;
159 + y -= cos(arc) * tmw.tmAscent;
160 + align = TA_LEFT | TA_TOP;
163 + if (font_is_bold(dc->gdiFont)) {
164 + if (GetMapMode(hdc) == MM_TEXT)
165 + flags |= ETO_BOLD_FLAG1;
167 + flags |= ETO_BOLD_FLAG2;
170 + bAtFont = font_is_rotate(dc->gdiFont);
172 + if( str!=NULL && count!=0 && bAtFont) {
173 + if (isalnum((int)str[0]))
174 + if((str[0] >= 0x0030 && str[0] <= 0x0039) /* number */
175 + || (str[0] >= 0x0041 && str[0] <= 0x005A) /* case letter */
176 + || (str[0] >= 0x0061 && str[0] <= 0x007A)) /* letter */
183 + double arc2 = (lf.lfEscapement - 900) * M_PI / 1800;
185 + if (!(lf.lfEscapement - 900) % 900)
186 + flags |= ETO_ROTATE;
188 + for(i = 0; i < count; i++) {
190 + case 0x201c: /* "(left) */
193 + case 0x201d: /* "(right) */
196 + case 0x2018: /* '(left) */
199 + case 0x2019: /*'(right) */
202 + case 0x300a: /* << */
205 + case 0x300b: /* >> */
212 + lfCloneFromDC(dc, &lf);
214 + hf = CreateFontIndirectW(&lf);
215 + hfOld = SelectObject(hdc, hf);
223 + GetTextMetricsW(hdc, &tm);
224 + x += sin(arc2) * tm.tmHeight;
225 + y += cos(arc2) * tm.tmHeight;
233 if (!dc) return FALSE;
235 breakRem = dc->breakRem;
236 @@ -2067,6 +2175,12 @@
240 +#ifdef UNIFIED_KERNEL
242 + SelectObject(hdc, hfOld);
243 + SetTextAlign(hdc, prev_align);
249 @@ -2085,7 +2199,11 @@
251 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
253 +#ifdef UNIFIED_KERNEL
254 + return ExtTextOutW( hdc, x, y, 0, NULL, (LPWSTR)str, count, NULL );
256 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
261 @@ -2116,7 +2234,12 @@
262 BOOL WINAPI PolyTextOutW( HDC hdc, const POLYTEXTW *pptxt, INT cStrings )
264 for (; cStrings>0; cStrings--, pptxt++)
265 +#ifdef UNIFIED_KERNEL
266 + if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl,
267 + (LPWSTR)pptxt->lpstr, pptxt->n, pptxt->pdx ))
269 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
274 @@ -2348,9 +2471,31 @@
276 if(!dc) return GDI_ERROR;
278 +#ifdef UNIFIED_KERNEL
279 + if (dc->gdiFont && font_is_italic(dc->gdiFont)) {
281 + memset(&mat, 0, sizeof(MAT2));
283 + mat.eM11.value = 1;
284 + mat.eM12.value = 0;
285 + mat.eM21.value = 0;
286 + mat.eM22.value = 1;
289 + ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
290 + cbBuffer, lpBuffer, lpmat2);
292 + ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
293 + cbBuffer, lpBuffer, &mat);
295 + else if(dc->gdiFont)
296 + ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
297 + cbBuffer, lpBuffer, lpmat2);
300 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
301 cbBuffer, lpBuffer, lpmat2);
306 diff -urN wine-1.0/dlls/gdi32/freetype.c wine-1.0-uk/dlls/gdi32/freetype.c
307 --- wine-1.0/dlls/gdi32/freetype.c 2008-06-17 22:07:31.000000000 +0800
308 +++ wine-1.0-uk/dlls/gdi32/freetype.c 2009-08-19 13:44:51.000000000 +0800
313 +#ifdef UNIFIED_KERNEL
317 #ifdef HAVE_CARBON_CARBON_H
318 #define LoadResource __carbon_LoadResource
320 MAKE_FUNCPTR(FT_Init_FreeType);
321 MAKE_FUNCPTR(FT_Load_Glyph);
322 MAKE_FUNCPTR(FT_Matrix_Multiply);
323 +#ifdef FT_MULFIX_INLINED
324 +#define pFT_MulFix FT_MULFIX_INLINED
326 MAKE_FUNCPTR(FT_MulFix);
328 MAKE_FUNCPTR(FT_New_Face);
329 MAKE_FUNCPTR(FT_New_Memory_Face);
330 MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
335 +#ifdef UNIFIED_KERNEL
343 static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph);
345 +#ifdef UNIFIED_KERNEL
346 +inline BOOL font_is_rotate(GdiFont *font)
348 + return font->rotate;
351 +inline BOOL font_is_italic(GdiFont *font)
353 + return font-> charset && font->fake_italic;
356 +inline BOOL font_is_bold(GdiFont *font)
358 + return font->fake_bold && font->charset;
361 +extern void lfCloneFromDC(DC *dc, LOGFONTW *lf)
363 + LOGFONTW *sourlf = &(((dc->gdiFont)->font_desc).lf);
364 + if(sourlf->lfFaceName == NULL)
366 + lf->lfHeight = sourlf->lfHeight;
367 + lf->lfWidth = sourlf->lfWidth;
368 + lf->lfEscapement = sourlf->lfEscapement + 900;
369 + lf->lfOrientation = sourlf->lfOrientation;
370 + lf->lfWeight = sourlf->lfWeight;
371 + lf->lfItalic = sourlf->lfItalic;
372 + lf->lfUnderline = sourlf->lfUnderline;
373 + lf->lfStrikeOut = sourlf->lfStrikeOut;
374 + lf->lfCharSet = sourlf->lfCharSet;
375 + lf->lfOutPrecision = sourlf->lfOutPrecision;
376 + lf->lfClipPrecision = sourlf->lfClipPrecision;
377 + lf->lfQuality = lf->lfQuality;
378 + lf->lfPitchAndFamily = sourlf->lfPitchAndFamily;
379 + if(sourlf->lfFaceName[0] != '\0' && sourlf->lfFaceName[0] == 0x0040)/* '@' unicode */
382 + while(sourlf->lfFaceName[i])
384 + lf->lfFaceName[i] = sourlf->lfFaceName[i];
387 + lf->lfFaceName[i] = 0x0;
391 + strcpyW(lf->lfFaceName, sourlf->lfFaceName);
394 + FindEnFontName(lf->lfFaceName);
396 + TRACE("CloneFontConverted: %s\n", debugstr_w(lf->lfFaceName));
399 +extern void GetRotate(DC *dc, LOGFONTW lf)
401 + dc->gdiFont->font_desc.lf.lfEscapement = lf.lfEscapement;
402 + dc->gdiFont->font_desc.lf.lfOrientation = lf.lfOrientation;
405 /****************************************
406 * Notes on .fon files
408 @@ -2343,7 +2413,9 @@
409 LOAD_FUNCPTR(FT_Init_FreeType)
410 LOAD_FUNCPTR(FT_Load_Glyph)
411 LOAD_FUNCPTR(FT_Matrix_Multiply)
412 +#ifndef FT_MULFIX_INLINED
413 LOAD_FUNCPTR(FT_MulFix)
415 LOAD_FUNCPTR(FT_New_Face)
416 LOAD_FUNCPTR(FT_New_Memory_Face)
417 LOAD_FUNCPTR(FT_Outline_Get_Bitmap)
418 @@ -3200,6 +3272,10 @@
422 +#ifdef UNIFIED_KERNEL
423 + if (lf.lfFaceName[0] != '\0' && lf.lfFaceName[0] == 0x0040)
424 + ret->rotate = TRUE;
426 memcpy(&ret->font_desc.matrix, &dc->xformWorld2Vport, sizeof(FMAT2));
427 ret->font_desc.lf = lf;
428 ret->font_desc.can_use_bitmap = can_use_bitmap;
429 @@ -3217,17 +3293,24 @@
430 if(!strcmpiW(lf.lfFaceName, SymbolW))
431 lf.lfCharSet = SYMBOL_CHARSET;
433 +#ifndef UNIFIED_KERNEL
434 if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
435 - switch(lf.lfCharSet) {
436 - case DEFAULT_CHARSET:
437 - csi.fs.fsCsb[0] = 0;
440 - FIXME("Untranslated charset %d\n", lf.lfCharSet);
441 - csi.fs.fsCsb[0] = 0;
446 + if( lf.lfCharSet == DEFAULT_CHARSET || lf.lfCharSet == ANSI_CHARSET) {
447 + if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCODEPAGE))
448 + csi.fs.fsCsb[0] = 0;
449 + } else if(!TranslateCharsetInfo((DWORD*)(INT)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
451 + switch(lf.lfCharSet) {
452 + case DEFAULT_CHARSET:
453 + csi.fs.fsCsb[0] = 0;
456 + FIXME("Untranslated charset %d\n", lf.lfCharSet);
457 + csi.fs.fsCsb[0] = 0;
463 if(lf.lfFaceName[0] != '\0') {
464 @@ -4262,10 +4345,20 @@
465 if (font->fake_italic) {
468 +#ifndef UNIFIED_KERNEL
469 slantMat.xx = (1 << 16);
470 slantMat.xy = ((1 << 16) >> 2);
472 slantMat.yy = (1 << 16);
474 + double arc = (font->font_desc.lf.lfEscapement - font->font_desc.lf.lfOrientation) * M_PI / 1800;
475 + double angle = 201 * M_PI / 1800;
477 + slantMat.xx = (1 << 16);
478 + slantMat.xy = abs(cos(arc) * sin(angle) * 0x10000L);
479 + slantMat.yx = - abs(sin(arc) * sin(angle) * 0x10000L);
480 + slantMat.yy = (1 << 16);
482 pFT_Matrix_Multiply(&slantMat, &transMat);
483 needsTransform = TRUE;
485 diff -urN wine-1.0/dlls/gdi32/gdi_private.h wine-1.0-uk/dlls/gdi32/gdi_private.h
486 --- wine-1.0/dlls/gdi32/gdi_private.h 2008-06-17 22:07:31.000000000 +0800
487 +++ wine-1.0-uk/dlls/gdi32/gdi_private.h 2009-08-18 16:11:13.000000000 +0800
489 /* Undocumented value for DIB's iUsage: Indicates a mono DIB w/o pal entries */
490 #define DIB_PAL_MONO 2
492 +#ifdef UNIFIED_KERNEL
493 +extern BOOL font_is_rotate(GdiFont *font);
494 +extern BOOL font_is_italic(GdiFont *font);
495 +extern BOOL font_is_bold(GdiFont *font);
496 +extern void lfCloneFromDC(DC *dc, LOGFONTW *lf);
497 +extern void log_hdc(HDC hdc, DC *dc);
498 +extern void GetRotate(DC *dc, LOGFONTW lf);
500 BOOL WINAPI FontIsLinked(HDC);
502 #endif /* __WINE_GDI_PRIVATE_H */
503 diff -urN wine-1.0/dlls/gdi32/metafile.c wine-1.0-uk/dlls/gdi32/metafile.c
504 --- wine-1.0/dlls/gdi32/metafile.c 2008-06-17 22:07:31.000000000 +0800
505 +++ wine-1.0-uk/dlls/gdi32/metafile.c 2009-08-18 16:11:13.000000000 +0800
507 case META_DIBSTRETCHBLT:
509 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[10]);
510 +#ifdef UNIFIED_KERNEL
511 + LPSTR bits = (LPSTR)info + bitmap_info_size( info, DIB_RGB_COLORS);
513 LPSTR bits = (LPSTR)info + bitmap_info_size( info, mr->rdParm[2] );
515 StretchDIBits( hdc, (SHORT)mr->rdParm[9], (SHORT)mr->rdParm[8], (SHORT)mr->rdParm[7],
516 (SHORT)mr->rdParm[6], (SHORT)mr->rdParm[5], (SHORT)mr->rdParm[4],
517 (SHORT)mr->rdParm[3], (SHORT)mr->rdParm[2], bits, info,
518 diff -urN wine-1.0/dlls/kernel32/debugger.c wine-1.0-uk/dlls/kernel32/debugger.c
519 --- wine-1.0/dlls/kernel32/debugger.c 2008-06-17 22:07:31.000000000 +0800
520 +++ wine-1.0-uk/dlls/kernel32/debugger.c 2009-08-19 10:13:55.000000000 +0800
522 #include "kernel_private.h"
523 #include "kernel16_private.h"
524 #include "wine/debug.h"
525 +#ifdef UNIFIED_KERNEL
529 WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
533 TRACE("(%p)\n", hProc);
535 +#ifdef UNIFIED_KERNEL
536 + struct handle_pair* pair = search_handle_pair(hProc);
538 + hProc= pair->wine_handle;
540 SERVER_START_REQ( debug_break )
543 diff -urN wine-1.0/dlls/kernel32/dosmem.c wine-1.0-uk/dlls/kernel32/dosmem.c
544 --- wine-1.0/dlls/kernel32/dosmem.c 2008-06-17 22:07:31.000000000 +0800
545 +++ wine-1.0-uk/dlls/kernel32/dosmem.c 2009-08-19 10:13:55.000000000 +0800
548 void * const low_64k = (void *)DOSMEM_64KB;
550 +#ifndef UNIFIED_KERNEL
551 /* check without the first 64K */
553 if (wine_mmap_is_in_reserved_area( low_64k, DOSMEM_SIZE - DOSMEM_64KB ) != 1)
556 /* inform the memory manager that there is a mapping here, but don't commit yet */
557 VirtualAlloc( addr, size, MEM_RESERVE | MEM_SYSTEM, PAGE_NOACCESS );
559 DOSMEM_protect = DOSMEM_64KB;
560 DOSMEM_dosmem = NULL;
561 return (char *)0xf0000; /* store sysmem in high addresses for now */
562 diff -urN wine-1.0/dlls/kernel32/process.c wine-1.0-uk/dlls/kernel32/process.c
563 --- wine-1.0/dlls/kernel32/process.c 2008-06-17 22:07:31.000000000 +0800
564 +++ wine-1.0-uk/dlls/kernel32/process.c 2009-08-19 10:22:11.000000000 +0800
566 #include "wine/unicode.h"
567 #include "wine/debug.h"
569 +#ifdef UNIFIED_KERNEL
573 WINE_DEFAULT_DEBUG_CHANNEL(process);
574 WINE_DECLARE_DEBUG_CHANNEL(file);
575 WINE_DECLARE_DEBUG_CHANNEL(relay);
580 +#ifndef UNIFIED_KERNEL
581 /***********************************************************************
582 * open_builtin_exe_file
586 return wine_dll_load_main_exe( exename, error, error_size, test_only, file_exists );
591 /***********************************************************************
596 +#ifndef UNIFIED_KERNEL
597 /***********************************************************************
607 /***********************************************************************
612 +#ifndef UNIFIED_KERNEL
613 __wine_main_argc = argc;
614 __wine_main_argv = argv;
616 __wine_main_wargv = wargv;
623 +#ifdef UNIFIED_KERNEL
625 + * process_init() has been removed from wine-0.9.53,
626 + * but Linux Unified Kernel will use it in ntdll.dll,
629 +BOOL process_init(void)
631 + static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
632 + PEB *peb = NtCurrentTeb()->Peb;
633 + RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
634 + BOOL got_environment = TRUE;
635 + HANDLE boot_event = 0;
636 + int *psocketfd = (int *)(params + 1);
638 + setbuf(stdout,NULL);
639 + setbuf(stderr,NULL);
641 + kernel32_handle = GetModuleHandleW(kernel32W);
645 + if (!params->Environment)
647 + /* Copy the parent environment */
648 + if (!build_initial_environment( __wine_main_environ )) return FALSE;
650 + /* convert old configuration to new format */
651 + convert_old_config();
653 + got_environment = set_registry_environment();
654 + set_additional_environment();
657 + init_windows_dirs();
658 + init_current_directory( ¶ms->CurrentDirectory );
660 + /* start wineboot */
662 + boot_event = start_wineboot();
666 + if (WaitForSingleObject( boot_event, 30000 )) WARN( "boot event wait timed out\n" );
667 + CloseHandle( boot_event );
668 + /* if we didn't find environment section, try again now that wineboot has run */
669 + if (!got_environment)
671 + set_registry_environment();
672 + set_additional_environment();
675 + set_library_wargv(__wine_main_argv);
681 /***********************************************************************
683 @@ -1168,6 +1235,7 @@
687 +#ifndef UNIFIED_KERNEL
688 /***********************************************************************
691 @@ -1291,6 +1359,7 @@
698 /***********************************************************************
699 @@ -1592,6 +1661,7 @@
703 +#ifndef UNIFIED_KERNEL
704 /***********************************************************************
707 @@ -1711,6 +1781,7 @@
708 HeapFree( GetProcessHeap(), 0, name );
714 /**********************************************************************
715 @@ -1755,6 +1826,7 @@
719 +#ifndef UNIFIED_KERNEL
720 /**********************************************************************
721 * CreateProcessW (KERNEL32.@)
723 @@ -1894,6 +1966,7 @@
724 TRACE( "started process pid %04x tid %04x\n", info->dwProcessId, info->dwThreadId );
730 /**********************************************************************
731 @@ -1945,6 +2018,1111 @@
732 CloseHandle( hFile );
735 +#ifdef UNIFIED_KERNEL
736 +#define PEB_BASE 0x7ffdf000
737 +extern void set_child_socket_fd(int fd);
738 +void BaseProcessStart(unsigned long start_address, void *param);
740 +extern VOID RtlRosR32AttribsToNativeAttribs(OUT OBJECT_ATTRIBUTES * NativeAttribs,
741 + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL);
743 +extern NTSTATUS WINAPI UkQuerySection(
744 + IN HANDLE SectionHandle,
745 + IN SECTION_INFORMATION_CLASS SectionInformationClass,
746 + OUT PVOID SectionInformation,
748 + OUT PULONG ResultLength);
750 +extern NTSTATUS CDECL
751 +RtlRosCreateUserThread(IN HANDLE ProcessHandle,
752 + IN POBJECT_ATTRIBUTES ObjectAttributes,
753 + IN BOOLEAN CreateSuspended,
754 + IN LONG StackZeroBits,
755 + IN OUT PULONG StackReserve OPTIONAL,
756 + IN OUT PULONG StackCommit OPTIONAL,
757 + IN PVOID BaseStartAddress,
758 + OUT PHANDLE ThreadHandle OPTIONAL,
759 + OUT PCLIENT_ID ClientId OPTIONAL,
760 + IN ULONG_PTR StartAddress,
761 + IN ULONG_PTR Parameter);
764 +UkOpenFile( PHANDLE handle, ACCESS_MASK access,
765 + POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
766 + ULONG sharing, ULONG options );
769 +UkCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
770 + const LARGE_INTEGER *size, ULONG protect,
771 + ULONG sec_flags, HANDLE file );
773 +NTSTATUS WINAPI NtClose( HANDLE Handle );
775 +static const char fakedll_signature[] = "Wine placeholder DLL";
777 +static BOOL IsFakeDll(HANDLE h)
779 + IMAGE_DOS_HEADER *dos;
781 + BYTE buffer[sizeof(*dos) + sizeof(fakedll_signature)];
783 + if (!ReadFile( h, buffer, sizeof(buffer), &size, NULL ) || size != sizeof(buffer))
785 + dos = (IMAGE_DOS_HEADER *)buffer;
786 + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return FALSE;
787 + if (dos->e_lfanew < size) return FALSE;
788 + return !memcmp( dos + 1, fakedll_signature, sizeof(fakedll_signature) );
791 +static BOOL IsValidPEApp(LPCWSTR AppName)
795 + handle = CreateFileW(AppName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
796 + if (handle == INVALID_HANDLE_VALUE)
798 + if (IsFakeDll(handle)) {
799 + CloseHandle(handle);
802 + CloseHandle(handle);
806 +#ifdef UNIFIED_KERNEL_EXESO
808 +extern char *get_dlldir(char **default_path);
809 +static BOOL NativeToBuiltin(LPWSTR Native, LPWSTR Builtin, unsigned BuiltinLen)
811 + char *prefix = NULL;
813 + char name[MAX_PATH];
816 + struct stat stat_buf;
818 + p = strrchrW(Native, '\\');
824 + get_dlldir(&prefix);
826 + len = strlen(prefix);
827 + memcpy(name, prefix, len);
829 + WideCharToMultiByte(CP_UNIXCP, 0, p, strlenW(p) + 1, name + len, sizeof(name) - len, 0, NULL);
838 + if (strcasecmp(name + len - 4, ".exe")) {
839 + memcpy(name + len, ".exe.so", sizeof(".exe.so"));
840 + len += sizeof(".exe.so") - 1;
843 + memcpy(name + len, ".so", sizeof(".so"));
844 + len += sizeof(".so") - 1;
847 + if (!stat(name, &stat_buf)) {
848 + MultiByteToWideChar(CP_UNIXCP, 0, name, len + 1, Builtin, BuiltinLen);
854 +static BOOL SearchApplication(LPWSTR AppName, LPWSTR NativeAppName,
855 + unsigned NativeAppNameLen, LPWSTR BuiltinAppName,
856 + unsigned BuiltinAppNameLen, PBOOL UseNative)
858 + WCHAR dotExe[] = {L'.',L'e',L'x',L'e', 0};
859 + BOOL Found = FALSE;
861 + if (SearchPathW(NULL, AppName, dotExe, NativeAppNameLen, NativeAppName, NULL)) {
862 + /* found pe format application */
863 + if (!IsValidPEApp(NativeAppName)) {
864 + if (NativeToBuiltin(NativeAppName, BuiltinAppName, BuiltinAppNameLen)) {
866 + *UseNative = FALSE;
873 + if (NativeToBuiltin(AppName, BuiltinAppName, BuiltinAppNameLen)) {
875 + *UseNative = FALSE;
882 +static inline void MakeBuiltinCmdLine(LPWSTR CmdLine, LPWSTR AppName, LPWSTR Params)
884 + WCHAR Quotation[] = {L'\"', 0};
887 + strcpyW(CmdLine + 1, AppName);
888 + strcatW(CmdLine, Quotation);
890 + strcatW(CmdLine, Params);
895 +static BOOL SearchApplication(LPWSTR AppName, LPWSTR NativeAppName,
896 + unsigned NativeAppNameLen, LPWSTR BuiltinAppName,
897 + unsigned BuiltinAppNameLen, PBOOL UseNative)
899 + WCHAR dotExe[] = {L'.',L'e',L'x',L'e', 0};
901 + if (SearchPathW(NULL, AppName, dotExe, NativeAppNameLen, NativeAppName, NULL)
902 + && IsValidPEApp(NativeAppName))
913 + * Helper for CreateProcessW: retrieve the file name to load from the
914 + * app name and command line. Store the file name in buffer, and
915 + * return a possibly modified command line.
917 + * FIXME: use CurDir to search for the executable file in the new working directory
919 + * modified from ReactOS
921 +static LPWSTR GetFileName(LPCWSTR CurDir, LPCWSTR AppName, LPWSTR CmdLine, LPWSTR Buffer,
922 + unsigned BufLen, LPWSTR BuiltinCmdLine, LPWSTR BuiltinAppName, unsigned BuiltinAppNameLen)
924 + WCHAR *Name, *Pos, *Ret = NULL;
925 + WCHAR Quotation[] = {L'\"', 0};
926 + BOOL UseNative = TRUE;
929 + /* if we have an app name, everything is easy */
931 + if (!SearchApplication((LPWSTR)AppName, Buffer, BufLen, BuiltinAppName,
932 + BuiltinAppNameLen, &UseNative)) {
933 + SetLastError(ERROR_FILE_NOT_FOUND);
937 + /* use the unmodified app name as file name */
939 + lstrcpynW(Buffer, AppName, BufLen );
941 + if (!Ret || !CmdLine[0]) {
942 + /* no command-line, create one */
943 + Ret = RtlAllocateHeap(GetProcessHeap(), 0,
944 + (strlenW(Buffer) + 3) * sizeof(WCHAR));
947 + strcpyW(Ret + 1, Buffer);
948 + strcatW(Ret, Quotation);
951 +#ifdef UNIFIED_KERNEL_EXESO
953 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, NULL);
959 + SetLastError(ERROR_INVALID_PARAMETER);
963 + /* first check for a quoted file name */
964 + if (L'"' == CmdLine[0] && (p = strchrW(CmdLine + 1, L'"'))) {
965 + int Len = p - CmdLine - 1;
967 + /* extract the quoted portion as file name */
968 + Name = RtlAllocateHeap(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR));
970 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
973 + memcpy(Name, CmdLine + 1, Len * sizeof(WCHAR));
976 + if (!SearchApplication(Name, Buffer, BufLen, BuiltinAppName, BuiltinAppNameLen, &UseNative)) {
977 + RtlFreeHeap(GetProcessHeap(), 0, Name);
978 + SetLastError(ERROR_FILE_NOT_FOUND);
983 + memcpy(Buffer, Name, Len * sizeof(WCHAR) + sizeof(WCHAR));
984 + strcpyW(Name, ++p); /* backup param */
987 + strcpyW(Ret + 1, Buffer);
988 + strcatW(Ret, Quotation);
989 + strcatW(Ret, Name);
991 +#ifdef UNIFIED_KERNEL_EXESO
993 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, (LPWSTR)++p);
996 + RtlFreeHeap(GetProcessHeap(), 0, Name);
1000 + /* now try the command-line word by word */
1001 + Name = RtlAllocateHeap(GetProcessHeap(), 0, (strlenW(CmdLine) + 1) * sizeof(WCHAR));
1003 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1012 + while (*p && L' ' != *p);
1015 + if (!SearchApplication(Name, Buffer, BufLen, BuiltinAppName, BuiltinAppNameLen, &UseNative))
1019 + strcpyW(Buffer, Name);
1022 +#ifdef UNIFIED_KERNEL_EXESO
1024 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, (LPWSTR)p);
1030 + RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
1034 + /* now build a new command-line with quotes */
1035 + Ret = RtlAllocateHeap(GetProcessHeap(), 0, (strlenW(CmdLine) + 3 + strlenW(Buffer)) * sizeof(WCHAR));
1037 + RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
1038 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1042 + strcpyW(Ret + 1, Buffer);
1043 + strcatW(Ret, Quotation);
1046 + RtlFreeHeap(GetProcessHeap(), 0, Name);
1050 +/* modified from ReactOS */
1051 +HANDLE KlMapFile(LPCWSTR lpApplicationName)
1054 + IO_STATUS_BLOCK IoStatusBlock;
1055 + UNICODE_STRING ApplicationNameString;
1056 + OBJECT_ATTRIBUTES ObjectAttributes;
1057 + PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
1063 + if (!RtlDosPathNameToNtPathName_U(lpApplicationName, &ApplicationNameString, NULL, NULL)) {
1064 + SetLastError(ERROR_PATH_NOT_FOUND);
1067 + InitializeObjectAttributes(&ObjectAttributes,
1068 + &ApplicationNameString,
1069 + OBJ_CASE_INSENSITIVE,
1071 + SecurityDescriptor);
1073 + /* Try to open the executable */
1075 + Status = UkOpenFile(&hFile,
1076 + SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
1077 + &ObjectAttributes,
1079 + FILE_SHARE_DELETE|FILE_SHARE_READ,
1080 + FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
1082 + RtlFreeUnicodeString (&ApplicationNameString);
1085 + SetLastError(Status);
1088 + Status = UkCreateSection(&hSection,
1089 + SECTION_ALL_ACCESS,
1098 + SetLastError(Status);
1105 +/* modified from ReactOS */
1106 +HANDLE KlCreateFirstThread(HANDLE ProcessHandle,
1107 + LPSECURITY_ATTRIBUTES lpThreadAttributes,
1108 + PSECTION_IMAGE_INFORMATION Sii,
1109 + LPTHREAD_START_ROUTINE lpStartAddress,
1110 + DWORD dwCreationFlags,
1111 + LPDWORD lpThreadId)
1113 + OBJECT_ATTRIBUTES oaThreadAttribs;
1114 + CLIENT_ID cidClientId;
1115 + PVOID pTrueStartAddress = NULL;
1116 + NTSTATUS nErrCode;
1119 + /* convert the thread attributes */
1120 + RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes);
1122 + /* native image */
1123 + if(Sii->ImageSubsystem != IMAGE_SUBSYSTEM_NATIVE)
1124 + pTrueStartAddress = NULL;
1126 + /* FIXME: nothing to do with win32 image */
1128 + ERR("Nothing to do with Win32 image!\n");
1130 + /* create the first thread */
1131 + nErrCode = RtlRosCreateUserThread(ProcessHandle,
1133 + dwCreationFlags & CREATE_SUSPENDED,
1135 + &(Sii->StackReserved),
1136 + &(Sii->StackCommit),
1137 + pTrueStartAddress,
1140 + (ULONG_PTR)lpStartAddress,
1141 + (ULONG_PTR)PEB_BASE);
1144 + SetLastError(nErrCode);
1150 + *lpThreadId = (DWORD)cidClientId.UniqueThread;
1155 +static NTSTATUS KlInitPeb(HANDLE ProcessHandle,
1156 + PRTL_USER_PROCESS_PARAMETERS Ppb,
1157 + PVOID * ImageBaseAddress,
1158 + ULONG ImageSubSystem)
1161 + PVOID EnvPtr = NULL;
1162 + PVOID ParentEnv = NULL;
1163 + PVOID PpbBase = NULL;
1165 + ULONG_PTR EnvSize = 0, PpbSize = 0;
1166 + ULONG_PTR EnvSize1 = 0;
1167 + ULONG_PTR ByteWritten = 0;
1168 + ULONG peb_base = 0x7FFDF000;
1171 + if (Ppb->Environment) {
1172 + ptr = Ppb->Environment;
1176 + EnvSize = ((ULONG)ptr - (ULONG)Ppb->Environment);
1177 + ParentEnv = Ppb->Environment;
1180 + if (EnvSize != 0) {
1181 + EnvSize1 = EnvSize;
1182 + Status = NtAllocateVirtualMemory(ProcessHandle,
1192 + NtWriteVirtualMemory(ProcessHandle,
1199 + /* create ppb in child space*/
1200 + PpbSize = Ppb->AllocationSize;
1202 + Status = NtAllocateVirtualMemory(ProcessHandle,
1211 + NtWriteVirtualMemory(ProcessHandle,
1217 + /* write environment */
1218 + offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
1219 + NtWriteVirtualMemory(ProcessHandle,
1220 + (PVOID)((ULONG)PpbBase + offset),
1225 + /* write point to ppb */
1226 + offset = FIELD_OFFSET(PEB, ProcessParameters);
1227 + NtWriteVirtualMemory(ProcessHandle,
1228 + (PVOID)(peb_base + offset),
1233 + /* FIXME: write image subsystem ? */
1234 + offset = FIELD_OFFSET(PEB, ImageSubSystem);
1235 + NtWriteVirtualMemory(ProcessHandle,
1236 + (PVOID)(peb_base + offset),
1238 + sizeof(ImageSubSystem),
1241 + /* read image base address */
1242 + offset = FIELD_OFFSET(PEB, ImageBaseAddress);
1243 + NtReadVirtualMemory(ProcessHandle,
1244 + (PVOID)(peb_base + offset),
1249 + return STATUS_SUCCESS;
1252 +#ifdef UNIFIED_KERNEL_EXESO
1253 +BOOL RunBuiltinApp(LPWSTR lpApplicationName,
1254 + LPWSTR lpCommandLine,
1255 + LPCWSTR NativeAppName,
1256 + LPWSTR NativeCmdLine,
1257 + LPSECURITY_ATTRIBUTES lpProcessAttributes,
1258 + LPSECURITY_ATTRIBUTES lpThreadAttributes,
1259 + BOOL bInheritHandles,
1260 + DWORD dwCreationFlags,
1261 + LPVOID lpEnvironment,
1262 + LPCWSTR lpCurrentDirectory,
1263 + LPSTARTUPINFOW lpStartupInfo,
1264 + LPPROCESS_INFORMATION lpProcessInformation)
1266 + WCHAR *TidyCmdLine = lpCommandLine;
1270 + HANDLE process_info;
1272 + BOOL success = FALSE;
1274 + OBJECT_ATTRIBUTES attr;
1275 + HANDLE wine_phandle, wine_thandle;
1277 + if (socketpair(PF_UNIX, SOCK_STREAM, 0, socketfd) == -1) {
1278 + SetLastError( ERROR_TOO_MANY_OPEN_FILES );
1281 + wine_server_send_fd(socketfd[1]);
1282 + close(socketfd[1]);
1284 + SERVER_START_REQ( new_process )
1286 + req->inherit_all = bInheritHandles;
1287 + req->create_flags = dwCreationFlags;
1288 + req->socket_fd = socketfd[1];
1289 + req->exe_file = NULL;
1290 + req->process_access = PROCESS_ALL_ACCESS;
1291 + req->process_attr = (lpProcessAttributes
1292 + && (lpProcessAttributes->nLength >= sizeof(*lpProcessAttributes))
1293 + && lpProcessAttributes->bInheritHandle)
1294 + ? OBJ_INHERIT : 0;
1295 + req->thread_access = THREAD_ALL_ACCESS;
1296 + req->thread_attr = (lpThreadAttributes
1297 + && (lpThreadAttributes->nLength >= sizeof(*lpThreadAttributes))
1298 + && lpThreadAttributes->bInheritHandle)
1299 + ? OBJ_INHERIT : 0;
1301 + if (lpStartupInfo && lpStartupInfo->dwFlags & STARTF_USESTDHANDLES) {
1302 + req->hstdin = lpStartupInfo->hStdInput;
1303 + req->hstdout = lpStartupInfo->hStdOutput;
1304 + req->hstderr = lpStartupInfo->hStdError;
1306 + req->hstdin = NtCurrentTeb()->Peb->ProcessParameters->hStdInput;
1307 + req->hstdout = NtCurrentTeb()->Peb->ProcessParameters->hStdOutput;
1308 + req->hstderr = NtCurrentTeb()->Peb->ProcessParameters->hStdError;
1311 + if (dwCreationFlags & CREATE_NEW_CONSOLE) {
1312 + /* TODO: handles for new console can't be controlled temporarily */
1313 + if (is_console_handle(req->hstdin))
1314 + req->hstdin = INVALID_HANDLE_VALUE;
1315 + if (is_console_handle(req->hstdout))
1316 + req->hstdout = INVALID_HANDLE_VALUE;
1317 + if (is_console_handle(req->hstderr))
1318 + req->hstderr = INVALID_HANDLE_VALUE;
1321 + Status = wine_server_call_err( req );
1323 + process_info = reply->info;
1324 + wine_phandle = reply->phandle;
1325 + wine_thandle = reply->thandle;
1330 + close(socketfd[0]);
1334 + if (pipe(pipefd) == -1) {
1335 + close(socketfd[0]);
1339 + if (!(pid = fork())) {
1340 + char socket_env[64];
1341 + char pipe_env[64];
1342 + char app_env[MAX_PATH + 64];
1343 + char cmdline_env[MAX_PATH * 4 + 64];
1344 + char **argv = build_argv(TidyCmdLine, 1);
1347 + sprintf(socket_env, "WINESERVERSOCKET=%u", socketfd[0]);
1348 + sprintf(pipe_env, "PIDTIDPIPE=%u", pipefd[1]);
1349 + strcpy(app_env, "NATIVEAPP=");
1350 + WideCharToMultiByte(CP_UNIXCP, 0, NativeAppName, strlenW(NativeAppName) + 1,
1351 + app_env + strlen(app_env), sizeof(app_env) - strlen(app_env), 0, NULL);
1352 + strcpy(cmdline_env, "NATIVECMDLINE=");
1353 + WideCharToMultiByte(CP_UNIXCP, 0, NativeCmdLine, strlenW(NativeCmdLine) + 1,
1354 + cmdline_env + strlen(cmdline_env), MAX_PATH * 4, 0, NULL);
1355 + putenv(socket_env);
1358 + putenv(cmdline_env);
1360 + wine_exec_wine_binary(0, argv, getenv("WINELOADER"));
1364 + close(socketfd[0]);
1367 + CloseHandle(process_info);
1372 + WaitForSingleObject(process_info, INFINITE);
1374 + SERVER_START_REQ(get_new_process_info)
1376 + req->info = process_info;
1377 + wine_server_call(req);
1378 + success = reply->success;
1382 + CloseHandle(process_info);
1384 + read(pipefd[0], &lpProcessInformation->dwProcessId, sizeof(lpProcessInformation->dwProcessId));
1385 + read(pipefd[0], &lpProcessInformation->dwThreadId, sizeof(lpProcessInformation->dwThreadId));
1393 + cid.UniqueProcess = (HANDLE)lpProcessInformation->dwProcessId;
1394 + cid.UniqueThread = (HANDLE)lpProcessInformation->dwThreadId;
1395 + memset(&attr, 0, sizeof(attr));
1396 + attr.Length = sizeof(attr);
1397 + Status = NtOpenProcess(&lpProcessInformation->hProcess, PROCESS_ALL_ACCESS, &attr, &cid);
1400 + Status = NtOpenThread(&lpProcessInformation->hThread, THREAD_ALL_ACCESS, &attr, &cid);
1402 + NtClose(lpProcessInformation->hProcess);
1411 +GetFullCmdLine(LPWSTR lpCommandLine)
1413 + WCHAR *cmdline = lpCommandLine;
1415 + WCHAR short_cmd[1024], long_cmd[1024], remain[1024];
1419 + if (*lpCommandLine == L'"') {
1420 + strcpyW(short_cmd, lpCommandLine + 1);
1421 + temp = strchrW(short_cmd, L'"');
1423 + strcpyW(remain, temp);
1428 + if (!GetLongPathNameW(short_cmd, long_cmd, 1024)) {
1429 + lstrcpynW(long_cmd, short_cmd, 1024);
1431 + *cmdline++ = L'"';
1433 + strcpyW(short_cmd, lpCommandLine);
1434 + temp = strchrW(short_cmd, L' ');
1436 + strcpyW(remain, temp);
1444 + if (!GetLongPathNameW(short_cmd, long_cmd, 1024)) {
1445 + lstrcpynW(long_cmd, short_cmd, 1024);
1449 + for (i = 0; ;i++) {
1450 + *cmdline++ = long_cmd[i];
1451 + if (long_cmd[i + 1] == L'\0')
1456 + strcatW(lpCommandLine, remain);
1460 +CreateProcessW(LPCWSTR lpApplicationName,
1461 + LPWSTR lpCommandLine,
1462 + LPSECURITY_ATTRIBUTES lpProcessAttributes,
1463 + LPSECURITY_ATTRIBUTES lpThreadAttributes,
1464 + BOOL bInheritHandles,
1465 + DWORD dwCreationFlags,
1466 + LPVOID lpEnvironment,
1467 + LPCWSTR lpCurrentDirectory,
1468 + LPSTARTUPINFOW lpStartupInfo,
1469 + LPPROCESS_INFORMATION lpProcessInformation)
1471 + HANDLE hSection, hProcess, hThread;
1472 + HANDLE hStdIn, hStdOut, hStdErr;
1473 + HANDLE process_info;
1474 + HANDLE wine_phandle, wine_thandle;
1475 + ULONG ProcAttributes = 0;
1476 + PVOID ProcSecurity = NULL;
1477 + PVOID ImageBaseAddress;
1480 + WCHAR* TidyCmdLine;
1481 + WCHAR Name[MAX_PATH];
1482 + WCHAR* TempCurrentDirectory;
1483 + WCHAR TempApplicationName[256];
1485 + WCHAR dotExe[] = {'.','e','x','e', 0};
1486 + WCHAR BuiltinCmdLine[MAX_PATH * 4] = {0}, BuiltinAppName[MAX_PATH] = {0};
1487 + WCHAR FullCmdLine[256] = {L'\0'};
1489 + UNICODE_STRING ImagePathName_U;
1490 + UNICODE_STRING CmdLine_U;
1491 + UNICODE_STRING CurrentDirectory_U;
1492 + UNICODE_STRING RuntimeInfo_U;
1493 + SECTION_IMAGE_INFORMATION Sii;
1494 + OBJECT_ATTRIBUTES ProcObjectAttributes;
1495 + PROCESS_PRIORITY_CLASS PriorityClass;
1496 + PRTL_USER_PROCESS_PARAMETERS ppb;
1497 + PROCESS_BASIC_INFORMATION ProcessBasicInfo;
1501 + TRACE("CreateProcessW(1:%s,2:%s,3:%p,4:%p,5:%d,6:%d,7:%p,8:%p,9:%p,10:%p)\n",
1502 + debugstr_w(lpApplicationName),
1503 + debugstr_w(lpCommandLine),
1504 + lpProcessAttributes,
1505 + lpThreadAttributes,
1509 + lpCurrentDirectory,
1511 + lpProcessInformation);
1513 + /* get long path name of commandline */
1514 + if (lpCommandLine) {
1515 + strcpyW(FullCmdLine, lpCommandLine);
1516 + GetFullCmdLine(FullCmdLine);
1519 + /* get file name */
1520 + TidyCmdLine = GetFileName(lpCurrentDirectory, lpApplicationName,
1521 + FullCmdLine, Name, sizeof(Name)/sizeof(WCHAR),
1522 + BuiltinCmdLine, BuiltinAppName, sizeof(BuiltinAppName) / sizeof(WCHAR));
1525 +#ifdef UNIFIED_KERNEL_EXESO
1526 + if (*BuiltinAppName && *BuiltinCmdLine) {
1527 + return RunBuiltinApp(BuiltinAppName,
1531 + lpProcessAttributes,
1532 + lpThreadAttributes,
1536 + lpCurrentDirectory,
1538 + lpProcessInformation);
1542 + /* deal with file name */
1543 + if (lpApplicationName && lpApplicationName[0])
1544 + strcpyW(TempApplicationName, lpApplicationName);
1546 + if (L'"' == TidyCmdLine[0]) {
1547 + /* command line: "*.exe" */
1548 + strcpyW(TempApplicationName, TidyCmdLine + 1);
1549 + tmp = strchrW(TempApplicationName, L'"');
1553 + /* command line: *.exe */
1554 + strcpyW(TempApplicationName, TidyCmdLine);
1555 + tmp = strchrW(TempApplicationName, L' ');
1556 + /* the command line with '"' and followed by ' ' is invalid*/
1557 + if (tmp) *tmp = L'\0';
1558 + else if ((tmp = strchrW(TempApplicationName, L'"'))) *tmp = L'\0';
1561 + tmp = max(strchrW(TempApplicationName, L'\\'), strchrW(TempApplicationName, L'/'));
1563 + tmp = TempApplicationName;
1564 + if (!strchrW(TempApplicationName, L'.'))
1565 + strcatW(TempApplicationName, dotExe);
1567 + /*TODO: search path*/
1569 + RtlInitUnicodeString(&ImagePathName_U, TempApplicationName);
1570 + RtlInitUnicodeString(&CmdLine_U, TidyCmdLine);
1572 + if (lpCurrentDirectory != NULL)
1573 + RtlInitUnicodeString(&CurrentDirectory_U,lpCurrentDirectory);
1575 + if(!(TempCurrentDirectory = RtlAllocateHeap(GetProcessHeap(), 0, 256))) {
1576 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1579 + GetCurrentDirectoryW(256, TempCurrentDirectory);
1580 + RtlInitUnicodeString(&CurrentDirectory_U, TempCurrentDirectory);
1581 + RtlFreeHeap(GetProcessHeap(), 0, TempCurrentDirectory);
1584 + /* FIXME: .cmd and .bat will not be processed */
1586 + /* map executable file */
1587 + hSection = KlMapFile(TempApplicationName);
1591 + /* TODO: 16bit applications
1595 + /* query section infomation */
1596 + Status = UkQuerySection(hSection, SectionImageInformation, &Sii, sizeof(Sii), NULL);
1598 + NtClose(hSection);
1599 + WARN("NtQuerySection() failed(Status %x)\n", Status);
1600 + SetLastError(RtlNtStatusToDosError(Status));
1604 + if (0 != (Sii.ImageCharacteristics & IMAGE_FILE_DLL)) {
1605 + NtClose(hSection);
1606 + WARN("Can't execute a DLL\n");
1607 + SetLastError(ERROR_INVALID_PARAMETER);
1611 + if (IMAGE_SUBSYSTEM_WINDOWS_GUI != Sii.ImageSubsystem
1612 + && IMAGE_SUBSYSTEM_WINDOWS_CUI != Sii.ImageSubsystem) {
1613 + NtClose(hSection);
1614 + WARN("Invalid subsystem %d\n", Sii.ImageSubsystem);
1615 + SetLastError(ERROR_INVALID_PARAMETER);
1619 + /* initialize object */
1620 + if(lpProcessAttributes) {
1621 + if(lpProcessAttributes->bInheritHandle)
1622 + ProcAttributes |= OBJ_INHERIT;
1623 + ProcSecurity = lpProcessAttributes->lpSecurityDescriptor;
1625 + InitializeObjectAttributes(&ProcObjectAttributes, NULL, ProcAttributes, NULL, ProcSecurity);
1627 + /* initialize priority */
1628 + PriorityClass.Foreground = FALSE;
1630 + if(dwCreationFlags & IDLE_PRIORITY_CLASS)
1631 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_IDLE;
1632 + else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
1633 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_BELOW_NORMAL;
1634 + else if(dwCreationFlags & NORMAL_PRIORITY_CLASS)
1635 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_NORMAL;
1636 + else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
1637 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_ABOVE_NORMAL;
1638 + else if(dwCreationFlags & HIGH_PRIORITY_CLASS)
1639 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_HIGH;
1640 + else if(dwCreationFlags & REALTIME_PRIORITY_CLASS)
1641 + /* FIXME - This is a privileged operation. If we don't have the privilege we should
1642 + rather use PROCESS_PRIOCLASS_HIGH. */
1643 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_REALTIME;
1645 + /* FIXME - what to do in this case? */
1646 + PriorityClass.PriorityClass = PROCESS_PRIOCLASS_NORMAL;
1648 + if (socketpair(PF_UNIX, SOCK_STREAM, 0, socketfd) == -1) {
1649 + SetLastError(ERROR_TOO_MANY_OPEN_FILES);
1652 + wine_server_send_fd(socketfd[1]);
1653 + close(socketfd[1]);
1654 + /* NtCreateProcess*/
1655 + NtCreateProcess(&hProcess,
1656 + PROCESS_ALL_ACCESS,
1657 + &ProcObjectAttributes,
1658 + NtCurrentProcess(),
1664 + NtSetInformationProcess(hProcess,
1665 + ProcessPriorityClass,
1667 + sizeof(PROCESS_PRIORITY_CLASS));
1669 + /* TODO: send set information message */
1672 + RtlInitUnicodeString(&RuntimeInfo_U, NULL);
1673 + if (lpStartupInfo) {
1674 + if (lpStartupInfo->lpReserved2) {
1676 + * ROUND_UP(xxx,2) + 2 is a dirty hack. RtlCreateProcessParameters
1677 + * assumes that the runtimeinfo is a unicode string and
1678 + * use RtlCopyUnicodeString for duplication.
1679 + * If is possible that this function overwrite the last information
1680 + * in runtimeinfo with the null terminator for the unicode string.
1682 + RuntimeInfo_U.Length = (lpStartupInfo->cbReserved2 + 1) & ~1;
1683 + RuntimeInfo_U.MaximumLength = (lpStartupInfo->cbReserved2 + 1) & ~1;
1684 + RuntimeInfo_U.Buffer = RtlAllocateHeap(GetProcessHeap(), 0,
1685 + RuntimeInfo_U.Length);
1686 + memcpy(RuntimeInfo_U.Buffer, lpStartupInfo->lpReserved2,
1687 + lpStartupInfo->cbReserved2);
1691 + set_child_socket_fd(socketfd[0]);
1693 + if (!(ppb = create_user_params( TempApplicationName, TidyCmdLine, lpCurrentDirectory,
1694 + lpEnvironment, dwCreationFlags, lpStartupInfo)))
1697 + set_child_socket_fd(0);
1699 + if (lpStartupInfo && lpStartupInfo->lpReserved2)
1700 + RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer);
1702 + /* copy ppb->CurrentDirectoryHandle */
1703 + if (ppb->CurrentDirectory.Handle)
1705 + NtDuplicateObject(NtCurrentProcess(),
1706 + ppb->CurrentDirectory.Handle,
1708 + &ppb->CurrentDirectory.Handle,
1711 + DUPLICATE_SAME_ACCESS);
1714 + /* close section */
1715 + NtClose(hSection);
1717 + /* initialize data to send to wine server */
1718 + NtQueryInformationProcess(hProcess,
1719 + ProcessBasicInformation,
1720 + &ProcessBasicInfo,
1721 + sizeof(ProcessBasicInfo),
1724 + lpProcessInformation->dwProcessId = (DWORD) ProcessBasicInfo.UniqueProcessId;
1726 + if (Sii.ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
1727 + /* do not create a console for GUI applications */
1728 + dwCreationFlags &= ~CREATE_NEW_CONSOLE;
1729 + dwCreationFlags |= DETACHED_PROCESS;
1730 + } else if (Sii.ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
1731 + if (!ppb->ConsoleHandle) /* FIXME: see dwCreationFlags */
1732 + dwCreationFlags |= CREATE_NEW_CONSOLE;
1736 + SERVER_START_REQ( new_process )
1738 + req->inherit_all = bInheritHandles;
1739 + req->create_flags = dwCreationFlags;
1740 + req->socket_fd = socketfd[1];
1741 + req->exe_file = NULL;
1742 + req->process_access = PROCESS_ALL_ACCESS;
1743 + if (lpStartupInfo && lpStartupInfo->dwFlags & STARTF_USESTDHANDLES) {
1744 + req->hstdin = lpStartupInfo->hStdInput;
1745 + req->hstdout = lpStartupInfo->hStdOutput;
1746 + req->hstderr = lpStartupInfo->hStdError;
1748 + req->hstdin = NtCurrentTeb()->Peb->ProcessParameters->hStdInput;
1749 + req->hstdout = NtCurrentTeb()->Peb->ProcessParameters->hStdOutput;
1750 + req->hstderr = NtCurrentTeb()->Peb->ProcessParameters->hStdError;
1753 + if (dwCreationFlags & CREATE_NEW_CONSOLE) {
1754 + /* TODO: handles for new console can't be controlled temporarily */
1755 + if (is_console_handle(req->hstdin))
1756 + req->hstdin = INVALID_HANDLE_VALUE;
1757 + if (is_console_handle(req->hstdout))
1758 + req->hstdout = INVALID_HANDLE_VALUE;
1759 + if (is_console_handle(req->hstderr))
1760 + req->hstderr = INVALID_HANDLE_VALUE;
1763 + hStdIn = req->hstdin;
1764 + hStdOut = req->hstdout;
1765 + hStdErr = req->hstderr;
1767 + Status = wine_server_call_err( req );
1769 + process_info = reply->info;
1770 + wine_phandle = reply->phandle;
1771 + wine_thandle = reply->thandle;
1776 + close(socketfd[0]);
1777 + SetLastError(RtlNtStatusToDosError(Status));
1781 + /* set handle, FIXME: no duplication is done */
1782 + ppb->hStdInput = hStdIn;
1783 + ppb->hStdOutput = hStdOut;
1784 + ppb->hStdError = hStdErr;
1786 + CloseHandle(process_info);
1789 + if (lpStartupInfo) {
1790 + ppb->dwFlags = lpStartupInfo->dwFlags;
1791 + if (ppb->dwFlags & STARTF_USESHOWWINDOW)
1792 + ppb->wShowWindow = lpStartupInfo->wShowWindow;
1794 + ppb->wShowWindow = SW_SHOWDEFAULT;
1795 + ppb->dwX = lpStartupInfo->dwX;
1796 + ppb->dwY = lpStartupInfo->dwY;
1797 + ppb->dwXSize = lpStartupInfo->dwXSize;
1798 + ppb->dwYSize = lpStartupInfo->dwYSize;
1799 + ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;
1803 + KlInitPeb(hProcess, ppb, &ImageBaseAddress, Sii.ImageSubsystem);
1805 + RtlDestroyProcessParameters(ppb);
1807 + /* create first thread */
1808 + hThread = KlCreateFirstThread(hProcess,
1809 + lpThreadAttributes,
1811 + (PVOID)((ULONG_PTR)ImageBaseAddress + (ULONG)Sii.EntryPoint),
1813 + &lpProcessInformation->dwThreadId);
1817 + /* store handle pair */
1818 + if (!store_handle_pair(hProcess, wine_phandle)) {
1819 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1822 + if (!store_handle_pair(hThread, wine_thandle)) {
1823 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1828 + * We use handles returned from system calls to do some stuff in CreateProcessW.
1829 + * But the process and thread handles are illegal in wine server, and they
1830 + * can't be used in other functions outside.
1833 + /* set process and thread handles*/
1834 + lpProcessInformation->hProcess = hProcess;
1835 + lpProcessInformation->hThread = hThread;
1841 /***********************************************************************
1843 @@ -3044,3 +4222,24 @@
1848 +#ifdef UNIFIED_KERNEL
1849 +void BaseProcessStart(unsigned long start_address, void *param)
1851 + unsigned long exit_code;
1852 + LPTHREAD_START_ROUTINE entry;
1856 + entry = (LPTHREAD_START_ROUTINE)start_address;
1857 + exit_code = entry(param);
1859 + __EXCEPT(UnhandledExceptionFilter)
1861 + exit_code = GetExceptionCode();
1865 + ExitProcess(exit_code);
1868 diff -urN wine-1.0/dlls/kernel32/sync.c wine-1.0-uk/dlls/kernel32/sync.c
1869 --- wine-1.0/dlls/kernel32/sync.c 2008-06-17 22:07:31.000000000 +0800
1870 +++ wine-1.0-uk/dlls/kernel32/sync.c 2009-08-19 10:13:55.000000000 +0800
1872 #include "kernel_private.h"
1874 #include "wine/debug.h"
1875 +#ifdef UNIFIED_KERNEL
1876 +#include "handle.h"
1879 WINE_DEFAULT_DEBUG_CHANNEL(sync);
1881 @@ -149,6 +152,108 @@
1882 return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
1885 +#ifdef UNIFIED_KERNEL
1888 + HANDLE mixed[MAXIMUM_WAIT_OBJECTS];
1889 + int pos[MAXIMUM_WAIT_OBJECTS];
1892 + BOOLEAN alertable;
1893 + LARGE_INTEGER * timeout;
1895 + HANDLE notify_event;
1898 +static DWORD CALLBACK uk_wait(LPVOID uk);
1900 +NTSTATUS mix_wait( DWORD count, const HANDLE *handles,
1901 + BOOLEAN wait_all, BOOLEAN alertable,
1902 + const LARGE_INTEGER *timeout )
1904 + HANDLE * base = (HANDLE *)handles;
1906 + HANDLE interface = NULL;
1907 + NTSTATUS status = STATUS_UNSUCCESSFUL;
1908 + struct mix_handle h_wine, h_uk;
1910 + memset(&h_wine, 0, sizeof(struct mix_handle));
1911 + h_wine.wait_all = wait_all;
1912 + h_wine.alertable = alertable;
1913 + h_wine.timeout = (LARGE_INTEGER *)timeout;
1915 + h_wine.notify_event = CreateEventA(NULL, 1, 0, NULL);
1916 + if (!h_wine.notify_event)
1919 + memcpy(&h_uk, &h_wine, sizeof(struct mix_handle));
1921 + h_wine.mixed[h_wine.count++] = h_wine.notify_event;
1923 + for (i = 0; i < count; i++, base++) {
1924 + if(IS_UK_HANDLE(*base)) {
1925 + h_uk.mixed[h_uk.count] = *base;
1926 + h_uk.pos[h_uk.count++] = i;
1928 + h_wine.mixed[h_wine.count] = *base;
1929 + h_wine.pos[h_wine.count++] = i;
1933 + interface = CreateThread(NULL, 0, uk_wait, (LPVOID)&h_uk, 0, NULL);
1935 + NtClose(h_wine.notify_event);
1939 + h_wine.ret = NtWaitForMultipleObjects(h_wine.count, h_wine.mixed, wait_all, alertable, timeout);
1941 + if (HIWORD(h_uk.ret)) /* is it an error code? */
1942 + status = h_uk.ret;
1943 + else if (HIWORD(h_wine.ret))
1944 + status = h_wine.ret;
1945 + else if (h_wine.ret == STATUS_TIMEOUT || h_uk.ret == STATUS_TIMEOUT)
1946 + status = STATUS_TIMEOUT;
1947 + else if (wait_all && (h_wine.ret == STATUS_WAIT_0 )) /* h_wine.ret shouldn't be other value */
1948 + status = h_uk.ret;
1949 + else if (h_wine.ret <= STATUS_WAIT_63) {
1950 + if (h_uk.ret >= STATUS_WAIT_0 && h_uk.ret < STATUS_WAIT_0 + h_uk.count)
1951 + status = STATUS_WAIT_0 +
1952 + min(h_uk.pos[h_uk.ret - STATUS_WAIT_0],
1953 + h_wine.pos[h_wine.ret - STATUS_WAIT_0]);
1954 + else if(h_uk.ret >= STATUS_ABANDONED_WAIT_0 &&
1955 + h_uk.ret < STATUS_ABANDONED_WAIT_0 + h_uk.count)
1956 + status = STATUS_ABANDONED_WAIT_0 +
1957 + min(h_uk.pos[h_uk.ret - STATUS_ABANDONED_WAIT_0],
1958 + h_wine.pos[h_wine.ret - STATUS_WAIT_0]);
1960 + status = h_wine.ret;
1963 + TerminateThread(interface, 0);
1964 + WaitForSingleObject(interface, INFINITE);
1965 + NtClose(interface);
1967 + NtClose(h_wine.notify_event);
1972 +static DWORD CALLBACK uk_wait(LPVOID uk)
1974 + struct mix_handle * h_uk = (struct mix_handle *)uk;
1976 + h_uk->ret = NtWaitForMultipleObjects(h_uk->count,
1982 + SetEvent(h_uk->notify_event);
1983 + SuspendThread(GetCurrentThread());
1988 /***********************************************************************
1989 * WaitForMultipleObjectsEx (KERNEL32.@)
1990 @@ -161,6 +266,11 @@
1991 HANDLE hloc[MAXIMUM_WAIT_OBJECTS];
1994 +#ifdef UNIFIED_KERNEL
1995 + HANDLE * handle_table = hloc;
1996 + int count_wine = 0, count_u = 0;
2000 if (count > MAXIMUM_WAIT_OBJECTS)
2002 @@ -189,8 +299,25 @@
2006 +#ifdef UNIFIED_KERNEL
2007 + for (; handle_table < hloc + count; handle_table++)
2008 + if (IS_UK_HANDLE(*handle_table))
2013 + mix = (count_u && count_wine) ? 1 : 0;
2016 +#ifndef UNIFIED_KERNEL
2017 status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable,
2018 get_nt_timeout( &time, timeout ) );
2021 + status = mix_wait( count, hloc, wait_all, alertable, get_nt_timeout(&time, timeout) );
2023 + status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable, get_nt_timeout(&time, timeout));
2026 if (HIWORD(status)) /* is it an error code? */
2028 diff -urN wine-1.0/dlls/kernel32/thread.c wine-1.0-uk/dlls/kernel32/thread.c
2029 --- wine-1.0/dlls/kernel32/thread.c 2008-06-17 22:07:31.000000000 +0800
2030 +++ wine-1.0-uk/dlls/kernel32/thread.c 2009-08-19 10:13:55.000000000 +0800
2032 #include "wine/debug.h"
2034 #include "kernel_private.h"
2035 +#ifdef UNIFIED_KERNEL
2036 +#include "handle.h"
2039 WINE_DEFAULT_DEBUG_CHANNEL(thread);
2041 +#ifdef UNIFIED_KERNEL
2042 +extern int server_abort_thread( int status );
2045 /***********************************************************************
2046 * CreateThread (KERNEL32.@)
2051 +#ifndef UNIFIED_KERNEL
2052 /***************************************************************************
2053 * CreateRemoteThread (KERNEL32.@)
2055 @@ -112,6 +119,148 @@
2060 +#define PAGE_SIZE 0x1000
2061 +#define ROUNDUP(a, b) ((((a) + (b) - 1)/(b))*(b))
2065 + char *str_pos; /* current position in strings buffer */
2066 + char *out_pos; /* current position in output buffer */
2067 + char strings[1024]; /* buffer for temporary strings */
2068 + char output[1024]; /* current output line */
2071 +struct ntdll_thread_data
2073 + DWORD fs; /* 1d4 TEB selector */
2074 + DWORD gs; /* 1d8 libc selector; update winebuild if you move this! */
2075 + struct debug_info *debug_info; /* 1dc info for debugstr functions */
2076 + int request_fd; /* 1e0 fd for sending server requests */
2077 + int reply_fd; /* 1e4 fd for receiving server replies */
2078 + int wait_fd[2]; /* 1e8 fd for sleeping server requests */
2079 + void *vm86_ptr; /* 1f0 data for vm86 mode */
2080 + void *pad[2]; /* 1f4 change this if you add fields! */
2083 +void ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)
2085 + volatile UINT uExitCode = 0;
2086 + struct debug_info debug_info;
2087 + struct ntdll_thread_data *thread_data;
2090 + thread_data = (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2;
2091 + thread_data->debug_info = &debug_info;
2092 + debug_info.str_pos = debug_info.strings;
2093 + debug_info.out_pos = debug_info.output;
2097 + uExitCode = (lpStartAddress)((PVOID)lpParameter);
2099 + __EXCEPT(UnhandledExceptionFilter)
2101 + uExitCode = GetExceptionCode();
2105 + ExitThread(uExitCode);
2109 +RtlRosCreateUserThread(IN HANDLE ProcessHandle,
2110 + IN POBJECT_ATTRIBUTES ObjectAttributes,
2111 + IN BOOLEAN CreateSuspended,
2112 + IN LONG StackZeroBits,
2113 + IN OUT PULONG StackReserve OPTIONAL,
2114 + IN OUT PULONG StackCommit OPTIONAL,
2115 + IN PVOID BaseStartAddress,
2116 + OUT PHANDLE ThreadHandle OPTIONAL,
2117 + OUT PCLIENT_ID ClientId OPTIONAL,
2118 + IN ULONG_PTR StartAddress,
2119 + IN ULONG_PTR Parameter);
2122 +CreateRemoteThread(HANDLE hProcess,
2123 + LPSECURITY_ATTRIBUTES lpThreadAttributes,
2124 + SIZE_T dwStackSize,
2125 + LPTHREAD_START_ROUTINE lpStartAddress,
2126 + LPVOID lpParameter,
2127 + DWORD dwCreationFlags,
2128 + LPDWORD lpThreadId)
2131 + CLIENT_ID cidClientId;
2132 + NTSTATUS nErrCode;
2133 + ULONG nStackReserve;
2134 + ULONG nStackCommit;
2135 + OBJECT_ATTRIBUTES oaThreadAttribs;
2136 + PIMAGE_NT_HEADERS pinhHeader = RtlImageNtHeader(NtCurrentTeb()->Peb->ImageBaseAddress);
2138 + /* FIXME: do more checks - e.g. the image may not have an optional header */
2139 + if(pinhHeader == NULL) {
2140 + nStackReserve = 0x100000;/* FIXME */
2141 + nStackCommit = PAGE_SIZE;
2143 + nStackReserve = pinhHeader->OptionalHeader.SizeOfStackReserve;
2144 + nStackCommit = pinhHeader->OptionalHeader.SizeOfStackCommit;
2147 + /* use defaults */
2148 + if(dwStackSize == 0);
2149 + /* dwStackSize specifies the size to reserve */
2150 + else if(dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION)
2151 + nStackReserve = dwStackSize;
2152 + /* dwStackSize specifies the size to commit */
2154 + nStackCommit = dwStackSize;
2156 + /* fix the stack reserve size */
2157 + if(nStackCommit > nStackReserve)
2158 + nStackReserve = ROUNDUP(nStackCommit, 0x100000);
2160 + /* initialize the attributes for the thread object */
2161 + InitializeObjectAttributes(&oaThreadAttribs,
2167 + if(lpThreadAttributes) {
2168 + /* make the handle inheritable */
2169 + if(lpThreadAttributes->bInheritHandle)
2170 + oaThreadAttribs.Attributes |= OBJ_INHERIT;
2172 + /* user-defined security descriptor */
2173 + oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
2176 + /* create the thread */
2177 + nErrCode = RtlRosCreateUserThread(hProcess,
2179 + dwCreationFlags & CREATE_SUSPENDED,
2183 + (LPTHREAD_START_ROUTINE)ThreadStartup,
2186 + (ULONG_PTR)lpStartAddress,
2187 + (ULONG_PTR)lpParameter);
2190 + SetLastError(nErrCode);
2196 + *lpThreadId = (DWORD)cidClientId.UniqueThread;
2203 /***********************************************************************
2204 @@ -165,7 +314,11 @@
2207 LdrShutdownProcess();
2208 +#ifndef UNIFIED_KERNEL
2211 + NtTerminateProcess(GetCurrentProcess(), code);
2216 @@ -185,9 +338,43 @@
2217 BOOL WINAPI TerminateThread( HANDLE handle, /* [in] Handle to thread */
2218 DWORD exit_code) /* [in] Exit code for thread */
2220 +#ifndef UNIFIED_KERNEL
2221 NTSTATUS status = NtTerminateThread( handle, exit_code );
2222 if (status) SetLastError( RtlNtStatusToDosError(status) );
2227 + HANDLE wine_handle;
2229 + if (GetCurrentThread() != handle) {
2230 + struct handle_pair * pair = search_handle_pair(handle);
2231 + wine_handle = pair->wine_handle;
2233 + wine_handle = handle;
2235 + SERVER_START_REQ( terminate_thread )
2237 + req->handle = wine_handle;
2238 + req->exit_code = exit_code;
2239 + status = wine_server_call( req );
2240 + self = !status && reply->self;
2241 + last = reply->last;
2247 + NtTerminateProcess(GetCurrentProcess(), exit_code);
2249 + return server_abort_thread(exit_code);
2253 + status = NtTerminateThread( handle, exit_code );
2254 + if (status) SetLastError( RtlNtStatusToDosError(status) );
2260 diff -urN wine-1.0/dlls/kernel32/virtual.c wine-1.0-uk/dlls/kernel32/virtual.c
2261 --- wine-1.0/dlls/kernel32/virtual.c 2008-06-17 22:07:31.000000000 +0800
2262 +++ wine-1.0-uk/dlls/kernel32/virtual.c 2009-08-19 10:13:55.000000000 +0800
2264 #include "winerror.h"
2265 #include "wine/exception.h"
2266 #include "wine/debug.h"
2267 +#include "handle.h"
2269 #include "kernel_private.h"
2273 static unsigned int page_size;
2275 +#ifdef UNIFIED_KERNEL
2278 +UkCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
2279 + const LARGE_INTEGER *size, ULONG protect,
2280 + ULONG sec_flags, HANDLE file );
2283 +UkOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr );
2286 +UkMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_ptr, ULONG zero_bits,
2287 + SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
2288 + SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect );
2291 +UkUnmapViewOfSection( HANDLE process, PVOID addr );
2294 /***********************************************************************
2295 * VirtualAlloc (KERNEL32.@)
2296 @@ -402,7 +421,14 @@
2297 size.u.LowPart = size_low;
2298 size.u.HighPart = size_high;
2300 +#ifdef UNIFIED_KERNEL
2301 status = NtCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
2303 + if ((hFile == INVALID_HANDLE_VALUE || !hFile) && attr.ObjectName)
2304 + status = UkCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
2306 + status = NtCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
2308 if (status == STATUS_OBJECT_NAME_EXISTS)
2309 SetLastError( ERROR_ALREADY_EXISTS );
2311 @@ -467,7 +493,13 @@
2313 if (access == FILE_MAP_COPY) access = FILE_MAP_READ;
2315 +#ifdef UNIFIED_KERNEL
2316 if ((status = NtOpenSection( &ret, access, &attr )))
2318 + if ((status = UkOpenSection( &ret, access, &attr )))
2319 + if (status == STATUS_OBJECT_NAME_NOT_FOUND)
2320 + if ((status = NtOpenSection( &ret, access, &attr )))
2323 SetLastError( RtlNtStatusToDosError(status) );
2325 @@ -532,12 +564,26 @@
2326 else if (access & FILE_MAP_COPY) protect = PAGE_WRITECOPY;
2327 else protect = PAGE_NOACCESS;
2329 +#ifdef UNIFIED_KERNEL
2330 if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
2331 &count, ViewShare, 0, protect )))
2333 SetLastError( RtlNtStatusToDosError(status) );
2337 + if (IS_UK_HANDLE(handle))
2338 + status = UkMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
2339 + &count, ViewShare, 0, protect );
2341 + status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
2342 + &count, ViewShare, 0, protect );
2345 + SetLastError( RtlNtStatusToDosError(status) );
2353 BOOL WINAPI UnmapViewOfFile( LPCVOID addr )
2355 NTSTATUS status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr );
2356 +#ifndef UNIFIED_KERNEL
2357 + if (status == STATUS_INVALID_PARAMETER) UkUnmapViewOfSection(GetCurrentProcess(), (void *)addr);
2359 if (status) SetLastError( RtlNtStatusToDosError(status) );
2362 diff -urN wine-1.0/dlls/Makedll.rules.in wine-1.0-uk/dlls/Makedll.rules.in
2363 --- wine-1.0/dlls/Makedll.rules.in 2008-06-17 22:07:31.000000000 +0800
2364 +++ wine-1.0-uk/dlls/Makedll.rules.in 2009-08-19 10:30:46.000000000 +0800
2366 # plus all variables required by the global Make.rules.in
2370 +KERNELVER = `uname -r | awk -F. '{print $$1}'`
2372 DLLFLAGS = @DLLFLAGS@
2374 IMPLIBEXT = @IMPLIBEXT@
2376 -DEFS = -D__WINESRC__ $(EXTRADEFS)
2378 +DEFS = -D__WINESRC__ $(EXTRADEFS) \
2379 + -DRUNTIME_LINKER=\"$(SLIBDIR)/ld-linux.so.$(KERNELVER)\" \
2380 + -DUNIFIED_KERNEL -DUNIFIED_KERNEL_EXESO
2381 BASEMODULE = $(MODULE:%.dll=%)
2382 MAINSPEC = $(BASEMODULE).spec
2383 SPEC_DEF = $(BASEMODULE).def
2385 # Rules for .so files
2387 $(MODULE).so: $(MAINSPEC) $(ALL_OBJS) Makefile.in
2388 - $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -shared $(SRCDIR)/$(MAINSPEC) $(ALL_OBJS) $(EXTRADLLFLAGS) -o $@ $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(DELAYIMPORTS:%=-Wb,-d%) $(ALL_LIBS)
2389 + $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -shared $(SRCDIR)/$(MAINSPEC) $(ALL_OBJS) $(EXTRADLLFLAGS) $(LDRPATH) -o $@ $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(DELAYIMPORTS:%=-Wb,-d%) $(ALL_LIBS)
2391 # Rules for .dll files
2393 diff -urN wine-1.0/dlls/ntdll/env.c wine-1.0-uk/dlls/ntdll/env.c
2394 --- wine-1.0/dlls/ntdll/env.c 2008-06-17 22:07:31.000000000 +0800
2395 +++ wine-1.0-uk/dlls/ntdll/env.c 2009-08-19 10:13:54.000000000 +0800
2398 WINE_DEFAULT_DEBUG_CHANNEL(environ);
2400 +#ifdef UNIFIED_KERNEL
2401 +extern int get_child_socket_fd();
2403 /******************************************************************************
2404 * RtlCreateEnvironment [NTDLL.@]
2407 SIZE_T size, total_size;
2410 +#ifdef UNIFIED_KERNEL
2414 RtlAcquirePebLock();
2415 cur_params = NtCurrentTeb()->Peb->ProcessParameters;
2417 + Desktop->MaximumLength
2418 + ShellInfo->MaximumLength
2419 + RuntimeInfo->MaximumLength);
2420 +#ifdef UNIFIED_KERNEL
2421 + size += sizeof(int); /* expand for socket fd */
2426 @@ -468,7 +477,13 @@
2427 params->Environment = Environment;
2428 /* all other fields are zero */
2430 +#ifndef UNIFIED_KERNEL
2433 + psocketfd = ptr = params + 1; /* expand for socket fd */
2434 + *psocketfd = get_child_socket_fd();
2435 + ptr = (int *)ptr + 1;
2437 append_unicode_string( &ptr, CurrentDirectoryName, ¶ms->CurrentDirectory.DosPath );
2438 append_unicode_string( &ptr, DllPath, ¶ms->DllPath );
2439 append_unicode_string( &ptr, ImagePathName, ¶ms->ImagePathName );
2440 diff -urN wine-1.0/dlls/ntdll/file.c wine-1.0-uk/dlls/ntdll/file.c
2441 --- wine-1.0/dlls/ntdll/file.c 2008-06-17 22:07:31.000000000 +0800
2442 +++ wine-1.0-uk/dlls/ntdll/file.c 2009-08-19 10:23:36.000000000 +0800
2444 #define SECSPERDAY 86400
2445 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
2447 +#ifdef UNIFIED_KERNEL
2448 +extern NTSTATUS WINAPI
2449 +NtWineService(struct __server_request_info * ReqMsg);
2452 /**************************************************************************
2453 * NtOpenFile [NTDLL.@]
2454 * ZwOpenFile [NTDLL.@]
2455 @@ -112,6 +117,26 @@
2456 return NtCreateFile( handle, access, attr, io, NULL, 0,
2457 sharing, FILE_OPEN, options, NULL, 0 );
2459 +#ifdef UNIFIED_KERNEL
2462 + * We use UkOpenFile with the system call NtOpenFile interface to do the same things,
2463 + * but NtOpenFile in wine is used.
2465 +NTSTATUS WINAPI UkOpenFile( PHANDLE handle, ACCESS_MASK access,
2466 + POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
2467 + ULONG sharing, ULONG options )
2470 + __asm__ __volatile__ (
2471 + "movl $0x58,%%eax\n\t"
2472 + "lea 8(%%ebp),%%edx\n\t"
2480 /**************************************************************************
2481 * NtCreateFile [NTDLL.@]
2482 @@ -174,7 +199,11 @@
2483 req->sharing = sharing;
2484 req->options = options;
2485 wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
2486 +#ifndef UNIFIED_KERNEL
2487 io->u.Status = wine_server_call( req );
2489 + io->u.Status = NtWineService(req);
2491 *handle = reply->handle;
2494 @@ -218,7 +247,11 @@
2495 wine_server_add_data( req, &objattr, sizeof(objattr) );
2496 if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
2497 wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
2498 +#ifndef UNIFIED_KERNEL
2499 io->u.Status = wine_server_call( req );
2501 + io->u.Status = NtWineService(req);
2503 *handle = reply->handle;
2509 result = read(fd, &fileio->buffer[fileio->already], fileio->count - fileio->already);
2510 +#ifndef UNIFIED_KERNEL
2511 if (needs_close) close( fd );
2516 @@ -454,9 +489,15 @@
2518 req->handle = handle;
2520 +#ifndef UNIFIED_KERNEL
2521 if (!(status = wine_server_call( req )) &&
2522 reply->read_timeout != TIMEOUT_INFINITE)
2523 timeouts->total = reply->read_timeout / -10000;
2525 + status = NtWineService(req);
2526 + if (!status && reply->read_timeout != TIMEOUT_INFINITE)
2527 + timeouts->total = reply->read_timeout / -10000;
2532 @@ -664,7 +705,11 @@
2533 req->async.apc = fileio_apc;
2534 req->async.event = hEvent;
2535 req->async.cvalue = cvalue;
2536 +#ifndef UNIFIED_KERNEL
2537 status = wine_server_call( req );
2539 + status = NtWineService(req);
2545 if (cvalue) NTDLL_AddCompletion( hFile, cvalue, status, total );
2548 +#ifndef UNIFIED_KERNEL
2549 if (needs_close) close( unix_handle );
2551 if (status == STATUS_SUCCESS)
2553 io_status->u.Status = status;
2555 if (cvalue) NTDLL_AddCompletion( file, cvalue, status, total );
2558 +#ifndef UNIFIED_KERNEL
2559 if (needs_close) close( unix_handle );
2561 if (status == STATUS_SUCCESS)
2563 io_status->u.Status = status;
2566 result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already );
2568 +#ifndef UNIFIED_KERNEL
2569 if (needs_close) close( fd );
2574 @@ -987,7 +1038,11 @@
2575 req->async.apc = fileio_apc;
2576 req->async.event = hEvent;
2577 req->async.cvalue = cvalue;
2578 +#ifndef UNIFIED_KERNEL
2579 status = wine_server_call( req );
2581 + status = NtWineService(req);
2586 @@ -1030,7 +1085,9 @@
2587 if (cvalue) NTDLL_AddCompletion( hFile, cvalue, status, total );
2590 +#ifndef UNIFIED_KERNEL
2591 if (needs_close) close( unix_handle );
2593 if (status == STATUS_SUCCESS)
2595 io_status->u.Status = status;
2596 @@ -1119,7 +1176,9 @@
2597 if (cvalue) NTDLL_AddCompletion( file, cvalue, status, total );
2600 +#ifndef UNIFIED_KERNEL
2601 if (needs_close) close( unix_handle );
2603 if (status == STATUS_SUCCESS)
2605 io_status->u.Status = status;
2606 @@ -1159,7 +1218,11 @@
2607 req->handle = async->handle;
2608 req->user_arg = async;
2609 wine_server_set_reply( req, async->buffer, async->size );
2610 +#ifndef UNIFIED_KERNEL
2611 if (!(status = wine_server_call( req )))
2613 + if (!(status = NtWineService(req)))
2615 io->Information = wine_server_reply_size( reply );
2618 @@ -1358,7 +1421,9 @@
2619 if (ioctl( fd, FIONREAD, &avail ) != 0)
2621 TRACE("FIONREAD failed reason: %s\n",strerror(errno));
2622 +#ifndef UNIFIED_KERNEL
2623 if (needs_close) close( fd );
2625 status = FILE_GetNtStatus();
2628 @@ -1374,7 +1439,9 @@
2629 ret = poll( &pollfd, 1, 0 );
2630 if (ret == -1 || (ret == 1 && (pollfd.revents & (POLLHUP|POLLERR))))
2632 +#ifndef UNIFIED_KERNEL
2633 if (needs_close) close( fd );
2635 status = STATUS_PIPE_BROKEN;
2638 @@ -1394,7 +1461,9 @@
2639 if (res >= 0) io->Information += res;
2642 +#ifndef UNIFIED_KERNEL
2643 if (needs_close) close( fd );
2648 @@ -1672,7 +1741,11 @@
2650 req->handle = hFile;
2652 +#ifndef UNIFIED_KERNEL
2653 io->u.Status = wine_server_call( req );
2655 + io->u.Status = NtWineService(req);
2657 if( io->u.Status == STATUS_SUCCESS )
2659 info->MaximumMessageSize = reply->max_msgsize;
2660 @@ -1696,7 +1769,9 @@
2661 int res = recv( fd, tmpbuf, size, MSG_PEEK );
2662 info->MessagesAvailable = (res > 0);
2663 info->NextMessageSize = (res >= 0) ? res : MAILSLOT_NO_MESSAGE;
2664 +#ifndef UNIFIED_KERNEL
2665 if (needs_close) close( fd );
2668 RtlFreeHeap( GetProcessHeap(), 0, tmpbuf );
2670 @@ -1710,7 +1785,11 @@
2671 SERVER_START_REQ( get_named_pipe_info )
2673 req->handle = hFile;
2674 +#ifndef UNIFIED_KERNEL
2675 if (!(io->u.Status = wine_server_call( req )))
2677 + if (!(io->u.Status = NtWineService(req)))
2680 pli->NamedPipeType = (reply->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) ?
2681 FILE_PIPE_TYPE_MESSAGE : FILE_PIPE_TYPE_BYTE;
2682 @@ -1734,7 +1813,9 @@
2683 io->u.Status = STATUS_NOT_IMPLEMENTED;
2686 +#ifndef UNIFIED_KERNEL
2687 if (needs_close) close( fd );
2689 if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
2690 return io->u.Status;
2692 @@ -1827,7 +1908,9 @@
2696 +#ifndef UNIFIED_KERNEL
2697 if (needs_close) close( fd );
2700 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2702 @@ -1843,7 +1926,9 @@
2703 if (lseek( fd, info->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
2704 io->u.Status = FILE_GetNtStatus();
2706 +#ifndef UNIFIED_KERNEL
2707 if (needs_close) close( fd );
2710 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2712 @@ -1872,7 +1957,9 @@
2714 io->u.Status = FILE_GetNtStatus();
2716 +#ifndef UNIFIED_KERNEL
2717 if (needs_close) close( fd );
2720 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2722 @@ -1886,7 +1973,11 @@
2723 req->handle = handle;
2724 req->flags = MAILSLOT_SET_READ_TIMEOUT;
2725 req->read_timeout = info->ReadTimeout.QuadPart;
2726 +#ifndef UNIFIED_KERNEL
2727 io->u.Status = wine_server_call( req );
2729 + io->u.Status = NtWineService(req);
2734 @@ -1902,7 +1993,11 @@
2735 req->handle = handle;
2736 req->chandle = info->CompletionPort;
2737 req->ckey = info->CompletionKey;
2738 +#ifndef UNIFIED_KERNEL
2739 io->u.Status = wine_server_call( req );
2741 + io->u.Status = NtWineService(req);
2746 @@ -2278,7 +2373,9 @@
2747 io->u.Status = STATUS_INVALID_PARAMETER;
2750 +#ifndef UNIFIED_KERNEL
2751 if (needs_close) close( fd );
2753 return io->u.Status;
2756 @@ -2304,7 +2401,11 @@
2757 SERVER_START_REQ( flush_file )
2759 req->handle = hFile;
2760 +#ifndef UNIFIED_KERNEL
2761 ret = wine_server_call( req );
2763 + ret = NtWineService(req);
2765 hEvent = reply->event;
2768 @@ -2348,7 +2449,11 @@
2769 req->count = count->QuadPart;
2770 req->shared = !exclusive;
2771 req->wait = !dont_wait;
2772 +#ifndef UNIFIED_KERNEL
2773 ret = wine_server_call( req );
2775 + ret = NtWineService(req);
2777 handle = reply->handle;
2778 async = reply->overlapped;
2780 @@ -2408,7 +2513,11 @@
2781 req->handle = hFile;
2782 req->offset = offset->QuadPart;
2783 req->count = count->QuadPart;
2784 +#ifndef UNIFIED_KERNEL
2785 status = wine_server_call( req );
2787 + status = NtWineService(req);
2792 @@ -2495,7 +2604,11 @@
2793 SERVER_START_REQ( cancel_async )
2795 req->handle = hFile;
2796 +#ifndef UNIFIED_KERNEL
2797 wine_server_call( req );
2799 + NtWineService(req);
2803 /* Let some APC be run, so that we can run the remaining APCs on hFile
2804 @@ -2557,7 +2670,11 @@
2805 req->read_timeout = timeout.QuadPart;
2806 wine_server_add_data( req, attr->ObjectName->Buffer,
2807 attr->ObjectName->Length );
2808 +#ifndef UNIFIED_KERNEL
2809 ret = wine_server_call( req );
2811 + ret = NtWineService(req);
2813 if( ret == STATUS_SUCCESS )
2814 *pHandle = reply->handle;
2816 diff -urN wine-1.0/dlls/ntdll/init.c wine-1.0-uk/dlls/ntdll/init.c
2817 --- wine-1.0/dlls/ntdll/init.c 1970-01-01 08:00:00.000000000 +0800
2818 +++ wine-1.0-uk/dlls/ntdll/init.c 2009-08-19 13:22:09.000000000 +0800
2823 + * Copyright (C) 2006 Insigme Co., Ltd
2825 + * This software has been developed while working on the Linux Unified Kernel
2826 + * project (http://linux.insigma.com.cn) in the Insigma Research Institute,
2827 + * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn).
2829 + * The project is sponsored by Insigma Co., Ltd.
2831 + * The authors can be reached at linux@insigma.com.cn.
2833 + * This program is free software; you can redistribute it and/or modify it
2834 + * under the terms of the GNU General Public License as published by the
2835 + * Free Software Foundation; either version 2 of the License, or (at your
2836 + * option) any later version.
2838 + * Revision History:
2839 + * Jan 2006 - Created.
2843 + * init.c: initiliase all that should be done before LdrInitializThunk
2846 +#ifdef UNIFIED_KERNEL
2848 +#include <stdlib.h>
2849 +#include <unistd.h>
2852 +#include <sys/types.h>
2853 +#include <sys/stat.h>
2854 +#include <stdarg.h>
2857 +#include "ntstatus.h"
2858 +#define WIN32_NO_STATUS
2859 +#include "windef.h"
2861 +#include "winternl.h"
2862 +#include "wine/library.h"
2863 +#include "wine/unicode.h"
2864 +#include "wine/server.h"
2865 +#include "wine/debug.h"
2867 +#include "ntdll_misc.h"
2868 +#include "handle.h"
2869 +#include "wine/list.h"
2871 +WINE_DEFAULT_DEBUG_CHANNEL(apc);
2873 +#define AT_BAK 1005
2874 +static WCHAR *SystemDir = NULL;
2875 +static WCHAR *WindowsDir = NULL;
2876 +struct list handle_refer = LIST_INIT(handle_refer);
2877 +static int handle_pairs;
2879 +extern struct _KUSER_SHARED_DATA *user_shared_data;
2881 +int child_socket_fd = 0;
2882 +typedef struct _wine_modref
2886 + struct _wine_modref **deps;
2888 +const char __dynamic_linker__[] __attribute__ ((section (".interp"))) = RUNTIME_LINKER;
2890 +static PEB_LDR_DATA ldr;
2891 +static RTL_BITMAP _tls_bitmap;
2892 +static RTL_BITMAP _tls_expansion_bitmap;
2893 +static RTL_BITMAP _fls_bitmap;
2894 +extern int __wine_main_argc;
2895 +extern char **__wine_main_argv;
2896 +extern char **__wine_main_environ;
2897 +extern unsigned long BaseProcessStartEntry;
2898 +extern LIST_ENTRY tls_links;
2900 +extern void debug_usage(void);
2901 +extern void parse_options(const char *str);
2902 +extern WINE_MODREF *alloc_module(HMODULE hModule, LPCWSTR filename);
2903 +extern void server_init_process(void);
2904 +extern size_t server_init_thread(int unix_pid, int unix_tid, void *entry_point);
2905 +extern int __cxa_atexit (void (*func) (void *), void *arg, void *d);
2906 +extern void build_dll_path(void);
2908 +void StartInterp(PIO_APC_ROUTINE ApcRoutine, void *stack,
2909 + void *interp_start, unsigned long bak_addr, void *Context);
2910 +extern void __wine_init_codepages(const union cptable *ansi, const union cptable *oem,
2911 + const union cptable *ucp);
2912 +extern const union cptable *wine_cp_get_table(unsigned int codepage);
2913 +extern NTSTATUS create_pe_sec_view(HANDLE hmodule);
2914 +typedef void (*BaseProcessStartFunc)(unsigned long, void *);
2915 +extern void uk_reserve_dos_area();
2917 +ElfW(auxv_t) *auxvec;
2920 +void set_child_socket_fd(int fd)
2922 + child_socket_fd = fd;
2925 +int get_child_socket_fd()
2927 + return child_socket_fd;
2930 +NTSTATUS WINAPI NtContinue(PCONTEXT param0, BOOLEAN param1)
2933 + __asm__ __volatile__ (
2934 + "movl $0x15, %%eax\n\t"
2935 + "lea 8(%%ebp), %%edx\n\t"
2943 +void ProcessStartForward(unsigned long start_address, void *peb)
2945 + BaseProcessStartFunc BaseProcessStart;
2947 + BaseProcessStart = (BaseProcessStartFunc)BaseProcessStartEntry;
2948 + BaseProcessStart(start_address, peb);
2951 +__attribute__ ((no_instrument_function)) void StartInterp();
2955 + * The linux interpreter here is used to link .so such as libwine.so for built-in dlls.
2956 + * ALl the dlls will be linked by ntdll.dll.so
2959 + ".globl StartInterp\n"
2960 + "StartInterp:\n\t"
2962 + "mov 0x28(%esp), %ecx\n\t" /* stack top used for linux arg */
2963 + "sub %esp, %ecx\n\t" /* stack size need backup */
2964 + "mov %esp, %esi\n\t"
2965 + "mov 0x30(%esp), %edi\n\t"
2966 + "mov %ecx, (%edi)\n\t" /* backup the size */
2967 + "add $0x4, %edi\n\t"
2968 + "shr $2, %ecx\n\t"
2970 + "mov 0x28(%esp), %ecx\n\t"
2971 + "mov 0x2c(%esp), %esi\n\t" /* Iosb, here in interpreter */
2972 + "mov %ecx, %esp\n\t"
2973 + "jmp *%esi\n" /* _start in interpreter */
2974 + /* finally jmp to AT_ENTRY */
2976 + ".globl StartThunk\n" /* set StartThunk to AT_ENTRY in kernel */
2978 + "xorl %ebp, %ebp\n\t" /* ABI need */
2979 + "movl (%esp), %esi\n\t" /* Pop the argument count. */
2980 + "leal 0x4(%esp), %ecx\n\t" /* argv starts just at the current stack top.*/
2981 + "movl %esp, %ebp\n\t"
2982 + /* Before pushing the arguments align the stack to a 16-byte
2983 + (SSE needs 16-byte alignment) boundary to avoid penalties from
2984 + misaligned accesses. */
2985 + "andl $0xfffffff0, %esp\n\t"
2986 + "pushl %eax\n\t" /* push garbage */
2987 + "pushl %eax\n\t" /* push garbage */
2988 + "pushl %eax\n\t" /* push garbage */
2990 + "pushl %edx\n\t" /* Push address of the shared library termination function. */
2991 + "pushl $0x0\n\t" /* __libc_csu_init */
2992 + "pushl %ecx\n\t" /* Push second argument: argv. */
2993 + "pushl %esi\n\t" /* Push first argument: argc. */
2994 + "call PrepareThunk\n\t"
2995 + "movl (%esp), %esp\n\t" /* restore %esp */
2996 + "movl (%eax), %ecx\n\t" /* stack size backuped */
2997 + "leal 0x4(%eax), %esi\n\t" /* stack data backuped in %esi */
2998 + "subl %ecx, %esp\n\t" /* restore %esp */
2999 + "movl %esp, %edi\n\t"
3000 + "shrl $0x2, %ecx\n\t"
3001 + "rep movsl\n\t" /* restore stack */
3003 + "ret\n" /* return from StartInterp */
3006 +static unsigned long extra_page = 0;
3008 +void __attribute__((stdcall, no_instrument_function))
3009 +KiUserApcDispatcher(PIO_APC_ROUTINE ApcRoutine, void *ApcContext,
3010 + void *Iosb, unsigned long Reserved, void *Context)
3013 + extra_page = Reserved;
3014 + StartInterp(ApcRoutine, ApcContext, Iosb, Reserved, Context);
3017 + ApcRoutine(ApcContext, Iosb, Reserved);
3019 + /* switch back to the interrupted context */
3020 + NtContinue((PCONTEXT)Context, 1);
3023 +char *get_wine_bindir()
3025 + char *wine_path, *bin_dir, *p, *temp;
3026 + char *paths = getenv("PATH");
3027 + char wine[] = "/wine";
3031 + wine_path = malloc(MAX_PATH + sizeof(wine));
3033 + paths = strdup(paths);
3035 + for (p = paths; *p != 0; p++) {
3036 + while (*p != ':' && *p)
3039 + strcpy(wine_path, temp);
3040 + strcat(wine_path, wine);
3042 + if (!stat(wine_path, &st))
3043 + if (S_ISREG(st.st_mode)) {
3044 + path_len = strrchr(wine_path, '/') - wine_path;
3045 + bin_dir = malloc((path_len + 1) * sizeof(char));
3046 + memcpy(bin_dir, wine_path, path_len);
3047 + bin_dir[path_len] = 0;
3060 +static NTSTATUS get_system_paths()
3062 + static const WCHAR windirW[] = {'w','i','n','d','i','r',0};
3063 + static const WCHAR sysdirW[] = {'w','i','n','s','y','s','d','i','r',0};
3064 + static const WCHAR default_windirW[] = {'c',':','\\','w','i','n','d','o','w','s',0};
3065 + static const WCHAR default_sysdirW[] = {'\\','s','y','s','t','e','m','3','2',0};
3066 + UNICODE_STRING sys_value,win_value;
3067 + UNICODE_STRING sys_name,win_name;
3070 + win_value.Length = 0;
3071 + win_value.MaximumLength = 0;
3072 + win_value.Buffer = NULL;
3073 + RtlInitUnicodeString(&win_name, windirW);
3074 + if (RtlQueryEnvironmentVariable_U(NULL, &win_name, &win_value) == STATUS_BUFFER_TOO_SMALL) {
3075 + path_len = win_value.Length;
3076 + win_value.MaximumLength = path_len + sizeof(WCHAR);
3077 + win_value.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, win_value.MaximumLength);
3078 + if (!win_value.Buffer)
3079 + return STATUS_NO_MEMORY;
3081 + RtlQueryEnvironmentVariable_U(NULL, &win_name, &win_value);
3082 + win_value.Buffer[path_len / sizeof(WCHAR)] = 0;
3083 + WindowsDir = win_value.Buffer;
3084 + } else /* this could be happened with the STATUS_VARIABLE_NOT_FOUND */
3085 + WindowsDir = (WCHAR *)default_windirW;
3087 + sys_value.Length = 0;
3088 + sys_value.MaximumLength = 0;
3089 + sys_value.Buffer = NULL;
3090 + RtlInitUnicodeString(&sys_name, sysdirW);
3091 + if (RtlQueryEnvironmentVariable_U(NULL, &sys_name, &sys_value) == STATUS_BUFFER_TOO_SMALL) {
3092 + path_len = sys_value.Length;
3093 + sys_value.MaximumLength = path_len + sizeof(WCHAR);
3094 + sys_value.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, sys_value.MaximumLength);
3095 + if (!sys_value.Buffer)
3096 + return STATUS_NO_MEMORY;
3098 + RtlQueryEnvironmentVariable_U(NULL, &sys_name, &sys_value);
3099 + sys_value.Buffer[path_len / sizeof(WCHAR)] = 0;
3100 + SystemDir = sys_value.Buffer;
3101 + } else { /* this could be happened with the STATUS_VARIABLE_NOT_FOUND */
3102 + path_len = strlenW(WindowsDir) * sizeof(WCHAR);
3103 + sys_value.Buffer = RtlAllocateHeap(GetProcessHeap(), 0,
3104 + path_len + sizeof(default_sysdirW));
3105 + if (!sys_value.Buffer)
3106 + return STATUS_NO_MEMORY;
3108 + memcpy(sys_value.Buffer, WindowsDir, path_len);
3109 + memcpy(sys_value.Buffer + path_len / sizeof(WCHAR), default_sysdirW,
3110 + sizeof(default_sysdirW));
3111 + SystemDir = sys_value.Buffer;
3114 + return STATUS_SUCCESS;
3117 +static WCHAR *get_dll_path(UNICODE_STRING* full_exe_name)
3119 + LPWSTR exe_path, dll_path;
3122 + int exe_path_len = 0;
3124 + WCHAR SystemDir16[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
3125 + WCHAR CurrentDirW[] = {'.',0};
3127 + /* get the length:
3129 + * + system dll path:
3131 + * + 32-bit system path
3132 + * + 16-bit system path
3136 + if (!full_exe_name)
3137 + exe_path = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
3139 + exe_path = full_exe_name->Buffer;
3141 + exe_path_len = (strrchrW(exe_path, '\\') - exe_path);
3142 + len += exe_path_len + 1;
3145 + len += strlenW(CurrentDirW) + 1;
3147 + get_system_paths();
3150 + len += strlenW(SystemDir) + 1;
3152 + len += strlenW(SystemDir16) + 1;
3155 + len += strlenW(WindowsDir) + 1;
3157 + /* make up dll path */
3158 + if ((p = dll_path = RtlAllocateHeap(GetProcessHeap(), 0, len * sizeof(WCHAR)))) {
3161 + memcpy(dll_path, exe_path, exe_path_len * sizeof(WCHAR));
3162 + p += exe_path_len;
3166 + /* system dll path */
3167 + strcpyW(p, CurrentDirW);
3171 + strcpyW(p, SystemDir);
3175 + strcpyW(p, SystemDir16);
3179 + strcpyW(p, WindowsDir);
3185 + dll_path[len - 1] = 0;
3192 +/* initialize all options at startup for Unified Kernel */
3193 +void __debug_init(void)
3197 + if ((wine_debug = getenv("WINEDEBUG")))
3199 + if (!strcmp(wine_debug, "help")) debug_usage();
3200 + parse_options(wine_debug);
3204 +#define NORMALIZE(x, addr) if (x) x = (typeof(x))((unsigned long)(x) + (unsigned long)(addr))
3205 +#define NORMALIZE_PARAMS(params) \
3209 + NORMALIZE((params)->CurrentDirectory.DosPath.Buffer, (params)); \
3210 + NORMALIZE((params)->DllPath.Buffer, (params)); \
3211 + NORMALIZE((params)->ImagePathName.Buffer, (params)); \
3212 + NORMALIZE((params)->CommandLine.Buffer, (params)); \
3213 + NORMALIZE((params)->WindowTitle.Buffer, (params)); \
3214 + NORMALIZE((params)->Desktop.Buffer, (params)); \
3215 + NORMALIZE((params)->ShellInfo.Buffer, (params)); \
3216 + NORMALIZE((params)->RuntimeInfo.Buffer, (params)); \
3220 +LPSTR WINAPI GetDir(void)
3222 + static char *cmdlineA; /* ASCII command line */
3225 + cmdlineA = (RtlUnicodeStringToAnsiString( &ansi,
3226 + &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath, TRUE) == STATUS_SUCCESS) ?
3227 + ansi.Buffer : NULL;
3235 + * Initializing all the parts that are done by wine-preloader
3236 + * All this initialization should be done before LdrInitializeThunk
3238 +void init_for_load()
3241 + PEB *peb = NtCurrentTeb()->Peb;
3242 + RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
3243 + IMAGE_NT_HEADERS *nt = RtlImageNtHeader(peb->ImageBaseAddress);
3244 + WCHAR *dll_path = NULL;
3245 + ANSI_STRING func_name;
3246 + UNICODE_STRING fullname;
3247 + struct ntdll_thread_data *thread_data;
3248 + struct ntdll_thread_regs *thread_regs;
3249 + static struct debug_info debug_info;
3251 + char socket_env[64];
3255 + if (params && (unsigned long)params->CommandLine.Buffer < (unsigned long)params) {
3256 + NORMALIZE((params)->CurrentDirectory.DosPath.Buffer, (params));
3257 + NORMALIZE((params)->DllPath.Buffer, (params));
3258 + NORMALIZE((params)->ImagePathName.Buffer, (params));
3259 + NORMALIZE((params)->CommandLine.Buffer, (params));
3260 + NORMALIZE((params)->WindowTitle.Buffer, (params));
3261 + NORMALIZE((params)->Desktop.Buffer, (params));
3262 + NORMALIZE((params)->ShellInfo.Buffer, (params));
3263 + NORMALIZE((params)->RuntimeInfo.Buffer, (params));
3266 + addr = (void *)0x7ffe0000;
3268 + NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
3269 + user_shared_data = addr;
3272 + thread_data = (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2;
3273 + thread_regs = (struct ntdll_thread_regs *)NtCurrentTeb()->SpareBytes1;
3274 + thread_data->debug_info = &debug_info;
3275 + debug_info.str_pos = debug_info.strings;
3276 + debug_info.out_pos = debug_info.output;
3278 + thread_data->fs = 0;
3279 + asm("mov %%fs, %0\n" : "=m"(thread_data->fs));
3281 + get_signal_stack_total_size();
3283 + /* debug initialization for debug log*/
3286 + /* initialize module lists */
3287 + InitializeListHead(&ldr.InLoadOrderModuleList);
3288 + InitializeListHead(&ldr.InMemoryOrderModuleList);
3289 + InitializeListHead(&ldr.InInitializationOrderModuleList);
3290 + NtCurrentTeb()->Peb->LdrData = &ldr;
3292 + /* initialize some fields in teb and peb */
3293 + NtCurrentTeb()->StaticUnicodeString.Length = 0;
3294 + NtCurrentTeb()->StaticUnicodeString.Buffer = NtCurrentTeb()->StaticUnicodeBuffer;
3295 + NtCurrentTeb()->StaticUnicodeString.MaximumLength = sizeof(NtCurrentTeb()->StaticUnicodeBuffer);
3297 + peb->TlsBitmap = &_tls_bitmap;
3298 + peb->TlsExpansionBitmap = &_tls_expansion_bitmap;
3299 + peb->FlsBitmap = &_fls_bitmap;
3300 + RtlInitializeBitMap(&_tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8);
3301 + RtlInitializeBitMap(&_tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
3302 + sizeof(peb->TlsExpansionBitmapBits) * 8);
3303 + RtlInitializeBitMap( &_fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 );
3305 + InitializeListHead(&tls_links);
3306 + InitializeListHead(&peb->FlsListHead);
3307 + InsertHeadList(&tls_links, &(NtCurrentTeb()->TlsLinks));
3309 + /* preset codepages before kernel32 being loaded */
3310 + __wine_init_codepages(wine_cp_get_table(1252),
3311 + wine_cp_get_table(437),
3312 + wine_cp_get_table(28591));
3314 + /* socket fd is located at the bottom of ppb*/
3316 + psocketfd = (int *)(params + 1);
3318 + sprintf(socket_env, "WINESERVERSOCKET=%u", *psocketfd);
3319 + putenv(socket_env);
3323 + virtual_init_threading();
3325 + /* connect to the server */
3326 + server_init_process();
3327 + server_init_thread(getpid(), gettid(), NULL);
3329 + /* create process heap */
3330 + if (!(peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL))) {
3331 + ERR("Error in create heap\n");
3335 + /* create view for main exe sections */
3336 + if (create_pe_sec_view(peb->ImageBaseAddress)) {
3337 + ERR("error in creating pe sections' views\n");
3341 + setenv("PWD",GetDir(),1);
3343 + /* allocate a module for main exe */
3344 + if (RtlSetCurrentDirectory_U(¶ms->CurrentDirectory.DosPath)) {
3345 + ERR( "error in setting current directory\n");
3349 + RtlDosPathNameToNtPathName_U(params->ImagePathName.Buffer, &fullname, NULL, NULL);
3350 + fullname.Buffer += 4; /* skip \??\ prefix */
3351 + fullname.Length -= 4;
3353 + /* initialize items in ppb */
3354 + params->wShowWindow = 1;
3356 + if (params->CommandLine.Buffer[0] == '.' && params->CommandLine.Buffer[1] == '/')
3357 + params->CommandLine.Buffer = params->CommandLine.Buffer + 2;
3359 + wm = alloc_module(peb->ImageBaseAddress, fullname.Buffer);
3360 + RtlFreeHeap(GetProcessHeap(), 0, fullname.Buffer);
3362 + ERR( "can't load %s\n", debugstr_w(fullname.Buffer));
3366 + /* set dll path */
3367 + dll_path = get_dll_path(&fullname);
3368 + RtlInitUnicodeString(¶ms->DllPath,dll_path);
3370 + /* register main exe on wine server */
3372 + SERVER_START_REQ(load_dll)
3374 + req->handle = 0; /* no handle of main exe */
3375 + req->base = peb->ImageBaseAddress;
3376 + req->size = nt->OptionalHeader.SizeOfImage;
3377 + req->dbg_offset = nt->FileHeader.PointerToSymbolTable;
3378 + req->dbg_size = nt->FileHeader.NumberOfSymbols;
3379 + req->name = &wm->ldr.FullDllName.Buffer;
3380 + wine_server_add_data(req, wm->ldr.FullDllName.Buffer, wm->ldr.FullDllName.Length);
3381 + wine_server_call(req);
3386 +__attribute__((stdcall))
3390 + void (*init) (void),
3391 + void (*rtld_fini)(void))
3394 + char *wine_path, *bin_dir;
3395 + char wine[] = "/wine";
3397 + if (__builtin_expect (rtld_fini != NULL, 1))
3398 + __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);
3400 + p = evp = argv + argc + 1;
3403 + auxvec = (ElfW(auxv_t) *)p;
3404 + auxvec_len = (unsigned long)argv[0] - (unsigned long)p;
3406 + bin_dir = get_wine_bindir();
3407 + wine_path = malloc(strlen(bin_dir) + sizeof(wine));
3408 + strcpy(wine_path, bin_dir);
3409 + strcat(wine_path, wine);
3412 + wine_init_argv0_path(wine_path);
3414 + __wine_main_argc = argc;
3415 + __wine_main_argv = argv;
3416 + __wine_main_environ = evp;
3421 + /* Call the initializer of the program, if any. */
3425 + /* .init in ntdll.dll.so */
3427 + NtCurrentTeb()->Peb->ProcessParameters->Environment = NULL;
3428 + return extra_page;
3431 +int store_handle_pair(HANDLE uk_handle, HANDLE wine_handle)
3433 + struct handle_pair *pair = malloc(sizeof(struct handle_pair));
3438 + pair->uk_handle = uk_handle;
3439 + pair->wine_handle = wine_handle;
3440 + list_add_before(&handle_refer, &pair->entry);
3442 + return ++handle_pairs;
3445 +struct handle_pair* search_handle_pair(HANDLE uk_handle)
3449 + LIST_FOR_EACH(p, &handle_refer)
3451 + struct handle_pair* pair = LIST_ENTRY(p, struct handle_pair,entry);
3452 + if (pair->uk_handle == uk_handle)
3458 +void delete_handle_pair(struct handle_pair* pair)
3460 + list_remove(&pair->entry);
3465 +#ifdef UNIFIED_KERNEL_EXESO
3466 +int UkDebug(unsigned long arg1, unsigned long arg2, unsigned long arg3)
3469 + __asm__ __volatile__(
3470 + "movl $234,%%eax\n\t"
3471 + "lea 8(%%ebp),%%edx\n\t"
3478 +IMAGE_NT_HEADERS **get_main_exe_ptr();
3479 +void *map_dll( const IMAGE_NT_HEADERS *nt_descr );
3481 +void __attribute__((regparm(0)))
3482 +ntdll_start_thunk(int unknown)
3484 + int *pargc = (int *)&unknown - 1;
3485 + char **argv = (char **)&unknown;
3488 + PEB *peb = NtCurrentTeb()->Peb;
3489 + IMAGE_NT_HEADERS **nt;
3491 + char *pipe = NULL;
3493 + RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters;
3494 + const char *env_socket = getenv("WINESERVERSOCKET");
3495 + int socket_fd = 0, *psocketfd;
3497 + uk_reserve_dos_area();
3498 + exeso = dlopen(argv[0], RTLD_NOW);
3500 + ERR("dlopen exeso failed: %s\n", dlerror());
3502 + nt = get_main_exe_ptr();
3503 + entry = (void *)(*nt)->OptionalHeader.AddressOfEntryPoint;
3504 + image_base = map_dll(*nt);
3505 + peb->ImageBaseAddress = image_base;
3509 + socket_fd = atoi(env_socket);
3511 + PrepareThunk(*pargc, argv, 0, 0);
3513 + * set socket fd to the bottom of ppb
3514 + * For built-in exe, we don't get the socket fd from ppb,
3515 + * and we set it here just for the further check
3517 + psocketfd = params + 1; /* expand for socket fd */
3518 + *psocketfd = socket_fd;
3520 + pipe = getenv("PIDTIDPIPE");
3523 + /* retrive of pid/tid should be after init_for_load() */
3524 + pid = NtCurrentTeb()->ClientId.UniqueProcess;
3525 + tid = NtCurrentTeb()->ClientId.UniqueThread;
3527 + write(fd, &pid, sizeof(pid));
3528 + write(fd, &tid, sizeof(tid));
3531 + LdrInitializeThunk(0,0,0,0);
3533 + asm __volatile__ ("movl %0, %%esp\n\t"
3534 + "pushl $0x7ffdf000\n\t"
3536 + "pushl $0xdeadbeef\n\t"
3538 + :: "r"(pargc), "r"(entry),
3539 + "r"(&ProcessStartForward)
3545 + void __attribute__((regparm(0)))
3546 +exeso_start_thunk(int unknown)
3553 diff -urN wine-1.0/dlls/ntdll/ld.s wine-1.0-uk/dlls/ntdll/ld.s
3554 --- wine-1.0/dlls/ntdll/ld.s 1970-01-01 08:00:00.000000000 +0800
3555 +++ wine-1.0-uk/dlls/ntdll/ld.s 2009-08-18 16:11:13.000000000 +0800
3557 +/* Script for --shared -z combreloc: shared library, combine & sort relocs */
3558 +OUTPUT_FORMAT("elf32-i386", "elf32-i386",
3562 +SEARCH_DIR("/usr/i386-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
3563 +/* Do we need any of these for elf?
3567 + /* Read-only sections, merged into text segment: */
3568 + . = 0x77fd0000 + SIZEOF_HEADERS;
3569 + .hash : { *(.hash) }
3570 + .dynsym : { *(.dynsym) }
3571 + .dynstr : { *(.dynstr) }
3572 + .gnu.version : { *(.gnu.version) }
3573 + .gnu.version_d : { *(.gnu.version_d) }
3574 + .gnu.version_r : { *(.gnu.version_r) }
3578 + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
3580 + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
3581 + *(.rel.data.rel.ro*)
3582 + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
3583 + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
3584 + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
3588 + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
3593 + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
3595 + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
3596 + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
3597 + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
3598 + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
3602 + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
3604 + .rel.plt : { *(.rel.plt) }
3605 + .rela.plt : { *(.rela.plt) }
3610 + .plt : { *(.plt) }
3613 + *(.text .stub .text.* .gnu.linkonce.t.*)
3614 + KEEP (*(.text.*personality*))
3615 + /* .gnu.warning sections are handled specially by elf32.em. */
3622 + PROVIDE (__etext = .);
3623 + PROVIDE (_etext = .);
3624 + PROVIDE (etext = .);
3625 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
3626 + .rodata1 : { *(.rodata1) }
3627 + .eh_frame_hdr : { *(.eh_frame_hdr) }
3628 + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
3629 + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
3630 + /* Adjust the address for the data segment. We want to adjust up to
3631 + the same address within the page on the next page up. */
3632 + . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);
3633 + /* Exception handling */
3634 + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
3635 + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
3636 + /* Thread Local Storage sections */
3637 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
3638 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
3639 + /* Ensure the __preinit_array_start label is properly aligned. We
3640 + could instead move the label definition inside the section, but
3641 + the linker would then create the section even if it turns out to
3642 + be empty, which isn't pretty. */
3643 + . = ALIGN(32 / 8);
3644 + .preinit_array : { KEEP (*(.preinit_array)) }
3645 + .init_array : { KEEP (*(.init_array)) }
3646 + .fini_array : { KEEP (*(.fini_array)) }
3649 + /* gcc uses crtbegin.o to find the start of
3650 + the constructors, so we make sure it is
3651 + first. Because this is a wildcard, it
3652 + doesn't matter if the user does not
3653 + actually link against crtbegin.o; the
3654 + linker won't look for a file to match a
3655 + wildcard. The wildcard also means that it
3656 + doesn't matter which directory crtbegin.o
3658 + KEEP (*crtbegin*.o(.ctors))
3659 + /* We don't want to include the .ctor section from
3660 + from the crtend.o file until after the sorted ctors.
3661 + The .ctor section from the crtend file contains the
3662 + end of ctors marker and it must be last */
3663 + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
3664 + KEEP (*(SORT(.ctors.*)))
3669 + KEEP (*crtbegin*.o(.dtors))
3670 + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
3671 + KEEP (*(SORT(.dtors.*)))
3674 + .jcr : { KEEP (*(.jcr)) }
3675 + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
3676 + .dynamic : { *(.dynamic) }
3677 + .got : { *(.got) }
3678 + . = DATA_SEGMENT_RELRO_END (12, .);
3679 + .got.plt : { *(.got.plt) }
3682 + *(.data .data.* .gnu.linkonce.d.*)
3683 + KEEP (*(.gnu.linkonce.d.*personality*))
3684 + SORT(CONSTRUCTORS)
3686 + .data1 : { *(.data1) }
3688 + PROVIDE (edata = .);
3693 + *(.bss .bss.* .gnu.linkonce.b.*)
3695 + /* Align here to ensure that the .bss section occupies space up to
3696 + _end. Align after .bss to ensure correct alignment even if the
3697 + .bss section disappears because there are no input sections. */
3698 + . = ALIGN(32 / 8);
3700 + . = ALIGN(32 / 8);
3702 + PROVIDE (end = .);
3703 + . = DATA_SEGMENT_END (.);
3704 + /* Stabs debugging sections. */
3705 + .stab 0 : { *(.stab) }
3706 + .stabstr 0 : { *(.stabstr) }
3707 + .stab.excl 0 : { *(.stab.excl) }
3708 + .stab.exclstr 0 : { *(.stab.exclstr) }
3709 + .stab.index 0 : { *(.stab.index) }
3710 + .stab.indexstr 0 : { *(.stab.indexstr) }
3711 + .comment 0 : { *(.comment) }
3712 + /* DWARF debug sections.
3713 + Symbols in the DWARF debugging sections are relative to the beginning
3714 + of the section so we begin them at 0. */
3716 + .debug 0 : { *(.debug) }
3717 + .line 0 : { *(.line) }
3718 + /* GNU DWARF 1 extensions */
3719 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
3720 + .debug_sfnames 0 : { *(.debug_sfnames) }
3721 + /* DWARF 1.1 and DWARF 2 */
3722 + .debug_aranges 0 : { *(.debug_aranges) }
3723 + .debug_pubnames 0 : { *(.debug_pubnames) }
3725 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
3726 + .debug_abbrev 0 : { *(.debug_abbrev) }
3727 + .debug_line 0 : { *(.debug_line) }
3728 + .debug_frame 0 : { *(.debug_frame) }
3729 + .debug_str 0 : { *(.debug_str) }
3730 + .debug_loc 0 : { *(.debug_loc) }
3731 + .debug_macinfo 0 : { *(.debug_macinfo) }
3732 + /* SGI/MIPS DWARF 2 extensions */
3733 + .debug_weaknames 0 : { *(.debug_weaknames) }
3734 + .debug_funcnames 0 : { *(.debug_funcnames) }
3735 + .debug_typenames 0 : { *(.debug_typenames) }
3736 + .debug_varnames 0 : { *(.debug_varnames) }
3737 + /DISCARD/ : { *(.note.GNU-stack) }
3739 diff -urN wine-1.0/dlls/ntdll/loader.c wine-1.0-uk/dlls/ntdll/loader.c
3740 --- wine-1.0/dlls/ntdll/loader.c 2008-06-17 22:07:31.000000000 +0800
3741 +++ wine-1.0-uk/dlls/ntdll/loader.c 2009-08-19 10:23:40.000000000 +0800
3743 WINE_DECLARE_DEBUG_CHANNEL(loaddll);
3744 WINE_DECLARE_DEBUG_CHANNEL(imports);
3746 +#ifdef UNIFIED_KERNEL
3747 +static int is_ntdll = 1;
3748 +unsigned long BaseProcessStartEntry;
3749 +unsigned long BaseThreadStartEntry;
3751 +BOOL (* process_init)(void);
3752 +void (* PTHREAD_Init)(void);
3753 +void (*ThreadStartup)(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);
3755 /* we don't want to include winuser.h */
3756 #define RT_MANIFEST ((ULONG_PTR)24)
3757 #define ISOLATIONAWARE_MANIFEST_RESOURCE_ID ((ULONG_PTR)2)
3758 @@ -687,7 +696,11 @@
3759 * Allocate a WINE_MODREF structure and add it to the process list
3760 * The loader_section must be locked while calling this function.
3762 +#ifndef UNIFIED_KERNEL
3763 static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
3765 +WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
3770 @@ -1333,10 +1346,21 @@
3771 builtin_load_info->status = STATUS_INVALID_IMAGE_FORMAT;
3774 +#ifndef UNIFIED_KERNEL
3776 size = nt->OptionalHeader.SizeOfImage;
3777 NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
3778 MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
3784 + size = nt->OptionalHeader.SizeOfImage;
3785 + NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
3786 + MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
3789 /* create the MODREF */
3791 if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename )))
3792 @@ -2350,6 +2374,67 @@
3796 +#ifdef UNIFIED_KERNEL
3798 + * get loaded dll's handle
3800 +void *get_dll_handle(char *dll_name)
3802 + WCHAR module_name[32];
3803 + PLIST_ENTRY mark, entry;
3805 + int len = strlen(dll_name);
3807 + if (len * sizeof(WCHAR) < sizeof(module_name)) {
3808 + ascii_to_unicode(module_name, dll_name, len );
3809 + module_name[len] = 0;
3811 + if (cached_modref && !strcmpiW(module_name, cached_modref->ldr.FullDllName.Buffer))
3812 + return cached_modref->ldr.SectionHandle;
3814 + mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
3815 + for (entry = mark->Flink; entry != mark; entry = entry->Flink) {
3816 + mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
3817 + if (!strcmpiW(module_name, mod->FullDllName.Buffer)) {
3818 + cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
3819 + return mod->SectionHandle;
3824 + WCHAR *ptr = RtlAllocateHeap(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
3825 + if (!ptr) return NULL;
3826 + ascii_to_unicode(ptr, dll_name, len);
3829 + if (cached_modref && !strcmpiW(ptr, cached_modref->ldr.FullDllName.Buffer))
3830 + return cached_modref->ldr.SectionHandle;
3832 + mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
3833 + for (entry = mark->Flink; entry != mark; entry = entry->Flink) {
3834 + mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
3835 + if (!strcmpiW(ptr, mod->FullDllName.Buffer)) {
3836 + cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
3837 + return mod->SectionHandle;
3840 + RtlFreeHeap( GetProcessHeap(), 0, ptr );
3846 + * find symbol in loaded builtin dll
3848 +void *find_builtin_symbol(const char *dll_name, const char *symbol)
3850 + void *dll_handle = get_dll_handle((char *)dll_name);
3852 + int err_size = sizeof(error);
3854 + return wine_dlsym(dll_handle, symbol, error, err_size);
3858 /***********************************************************************
3859 * attach_process_dlls
3860 @@ -2360,7 +2445,11 @@
3864 +#ifndef UNIFIED_KERNEL
3865 pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
3867 + sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
3870 RtlEnterCriticalSection( &loader_section );
3871 if ((status = process_attach( wm, (LPVOID)1 )) != STATUS_SUCCESS)
3872 @@ -2389,6 +2478,10 @@
3873 PEB *peb = NtCurrentTeb()->Peb;
3874 IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
3876 +#ifdef UNIFIED_KERNEL
3877 + wine_dll_set_callback(load_builtin_callback);
3878 + main_exe_file = 0;
3880 if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
3882 /* allocate the modref for the main exe (if not already done) */
3883 @@ -2411,22 +2504,49 @@
3884 stack_size = max( nt->OptionalHeader.SizeOfStackReserve, nt->OptionalHeader.SizeOfStackCommit );
3885 if (stack_size < 1024 * 1024) stack_size = 1024 * 1024; /* Xlib needs a large stack */
3887 +#ifndef UNIFIED_KERNEL
3888 if ((status = virtual_alloc_thread_stack( NULL, stack_size )) != STATUS_SUCCESS) goto error;
3890 if ((status = server_init_process_done()) != STATUS_SUCCESS) goto error;
3892 +#ifndef UNIFIED_KERNEL
3895 load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
3896 if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
3897 +#ifdef UNIFIED_KERNEL
3898 + /* get process start address from kernel32.dll*/
3899 + if (!(BaseProcessStartEntry = (unsigned long) find_builtin_symbol("kernel32.dll", "BaseProcessStart")))
3902 + if (!(process_init = find_builtin_symbol("kernel32.dll", "process_init")))
3905 + if (!(ThreadStartup = find_builtin_symbol("kernel32.dll", "ThreadStartup")))
3908 + if (!(unhandled_exception_filter = find_builtin_symbol("kernel32.dll", "UnhandledExceptionFilter")))
3915 if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto error;
3916 if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto error;
3918 +#ifndef UNIFIED_KERNEL
3919 status = wine_call_on_stack( attach_process_dlls, wm, NtCurrentTeb()->Tib.StackBase );
3921 + status = attach_process_dlls(wm);
3922 if (status != STATUS_SUCCESS) goto error;
3924 +#ifndef UNIFIED_KERNEL
3925 /* clear the stack contents before calling the main entry point, some broken apps need that */
3926 wine_anon_mmap( NtCurrentTeb()->Tib.StackLimit,
3927 (char *)NtCurrentTeb()->Tib.StackBase - (char *)NtCurrentTeb()->Tib.StackLimit,
3928 PROT_READ | PROT_WRITE, MAP_FIXED );
3931 if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
3933 @@ -2560,6 +2680,10 @@
3935 PLIST_ENTRY mark, entry;
3937 +#ifdef UNIFIED_KERNEL
3938 + WCHAR kernel32[] = {'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.' ,'d' ,'l' ,'l' , '\0'};
3939 + WCHAR ntdll[] = {'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', '\0'};
3942 RtlCreateUnicodeString( &windows_dir, windir );
3943 RtlCreateUnicodeString( &system_dir, sysdir );
3944 @@ -2571,6 +2695,12 @@
3946 LDR_MODULE *mod = CONTAINING_RECORD( entry, LDR_MODULE, InLoadOrderModuleList );
3948 +#ifdef UNIFIED_KERNEL
3949 + /* this should be done just for kernel32.dll and ntdll.dll */
3950 + if (strcmpiW(mod->BaseDllName.Buffer, kernel32)
3951 + && strcmpiW(mod->BaseDllName.Buffer, ntdll))
3954 assert( mod->Flags & LDR_WINE_INTERNAL );
3956 buffer = RtlAllocateHeap( GetProcessHeap(), 0,
3957 diff -urN wine-1.0/dlls/ntdll/Makefile.in wine-1.0-uk/dlls/ntdll/Makefile.in
3958 --- wine-1.0/dlls/ntdll/Makefile.in 2008-06-17 22:07:31.000000000 +0800
3959 +++ wine-1.0-uk/dlls/ntdll/Makefile.in 2009-08-18 16:11:13.000000000 +0800
3964 -EXTRALIBS = @IOKITLIB@
3965 +EXTRALIBS = @IOKITLIB@-ldl -lpthread
3966 EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000
3977 RC_SRCS = version.rc
3979 EXTRA_OBJS = relay32.o
3982 +LDRPATH += -Wl,--script,ld.s
3984 relay32.o: $(WINEBUILD)
3985 $(WINEBUILD) $(WINEBUILDFLAGS) -o $@ --relay32
3986 diff -urN wine-1.0/dlls/ntdll/nt.c wine-1.0-uk/dlls/ntdll/nt.c
3987 --- wine-1.0/dlls/ntdll/nt.c 2008-06-17 22:07:31.000000000 +0800
3988 +++ wine-1.0-uk/dlls/ntdll/nt.c 2009-08-19 10:22:26.000000000 +0800
3990 #include "winternl.h"
3991 #include "ntdll_misc.h"
3992 #include "wine/server.h"
3993 +#ifdef UNIFIED_KERNEL
3994 +#include "handle.h"
3997 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
4003 +#ifndef UNIFIED_KERNEL
4004 TRACE("(%p,0x%08x,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
4006 SERVER_START_REQ( open_token )
4007 @@ -110,6 +114,28 @@
4008 if (!ret) *TokenHandle = reply->token;
4012 + struct handle_pair* pair;
4014 + TRACE("(%p,0x%08x,%p)\n", ProcessHandle,DesiredAccess, TokenHandle);
4016 + SERVER_START_REQ( open_token )
4018 + if ((ProcessHandle != GetCurrentProcess())) {
4019 + if ((pair = search_handle_pair(ProcessHandle)))
4020 + req->handle = pair->wine_handle;
4022 + req->handle = NULL;
4024 + req->handle = ProcessHandle;
4025 + req->access = DesiredAccess;
4026 + req->attributes = 0;
4028 + ret = wine_server_call( req );
4029 + if (!ret) *TokenHandle = reply->token;
4040 +#ifndef UNIFIED_KERNEL
4041 TRACE("(%p,0x%08x,0x%08x,%p)\n",
4042 ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
4044 @@ -140,6 +167,32 @@
4045 if (!ret) *TokenHandle = reply->token;
4049 + struct handle_pair* pair;
4051 + TRACE("(%p,0x%08x,0x%08x,%p)\n",
4052 + ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
4054 + SERVER_START_REQ( open_token )
4056 + if ((ThreadHandle != (HANDLE) GetCurrentThread()))
4058 + if ((pair = search_handle_pair(ThreadHandle)))
4059 + req->handle = pair->wine_handle;
4061 + req->handle = NULL;
4064 + req->handle = ThreadHandle;
4065 + req->access = DesiredAccess;
4066 + req->attributes = 0;
4067 + req->flags = OPEN_TOKEN_THREAD;
4068 + if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF;
4069 + ret = wine_server_call( req );
4070 + if (!ret) *TokenHandle = reply->token;
4077 diff -urN wine-1.0/dlls/ntdll/ntdll_misc.h wine-1.0-uk/dlls/ntdll/ntdll_misc.h
4078 --- wine-1.0/dlls/ntdll/ntdll_misc.h 2008-06-17 22:07:31.000000000 +0800
4079 +++ wine-1.0-uk/dlls/ntdll/ntdll_misc.h 2009-08-18 16:11:13.000000000 +0800
4081 extern void server_init_process(void);
4082 extern NTSTATUS server_init_process_done(void);
4083 extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point );
4084 +#ifndef UNIFIED_KERNEL
4085 extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
4086 extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
4087 extern void DECLSPEC_NORETURN server_exit_thread( int status );
4088 extern void DECLSPEC_NORETURN server_abort_thread( int status );
4090 +extern void server_protocol_error( const char *err, ... );
4091 +extern void server_protocol_perror( const char *err );
4092 +extern void server_exit_thread( int status );
4093 +extern int server_abort_thread( int status );
4095 extern sigset_t server_block_set;
4096 extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset );
4097 extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset );
4098 diff -urN wine-1.0/dlls/ntdll/ntdll.spec wine-1.0-uk/dlls/ntdll/ntdll.spec
4099 --- wine-1.0/dlls/ntdll/ntdll.spec 2008-06-17 22:07:31.000000000 +0800
4100 +++ wine-1.0-uk/dlls/ntdll/ntdll.spec 2009-08-18 16:11:13.000000000 +0800
4102 @ stdcall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr)
4103 @ stdcall NtCreatePagingFile(long long long long)
4104 @ stdcall NtCreatePort(ptr ptr long long ptr)
4105 -@ stub NtCreateProcess
4106 +# @ stub NtCreateProcess
4107 # @ stub NtCreateProcessEx
4108 @ stub NtCreateProfile
4109 @ stdcall NtCreateSection(ptr long ptr ptr long long long)
4110 @@ -1392,3 +1392,32 @@
4111 @ cdecl wine_nt_to_unix_file_name(ptr ptr long long)
4112 @ cdecl wine_unix_to_nt_file_name(ptr ptr)
4113 @ cdecl __wine_init_windows_dir(wstr wstr)
4115 +# Linux Unified Kernel extensions
4116 +# All functions are modified from ReactOS
4119 +@ cdecl RtlRosCreateUserThread(long ptr long long ptr ptr ptr ptr ptr long long)
4122 +@ cdecl RtlRosR32AttribsToNativeAttribs(ptr ptr)
4125 +@ stdcall NtCreateProcess(long long ptr long long long long long)
4128 + # system call NtOpenFile
4129 +@ stdcall UkCreateSection(ptr long ptr ptr long long long)
4130 +@ stdcall UkOpenSection(ptr long ptr )
4131 +@ stdcall UkMapViewOfSection(ptr ptr ptr long long ptr ptr long long long)
4132 +@ stdcall UkUnmapViewOfSection(ptr ptr)
4133 +@ stdcall UkQuerySection(ptr long ptr long ptr)
4135 +@ stdcall UkOpenFile(ptr long ptr ptr long long)
4137 +@ stdcall set_child_socket_fd(long)
4138 +@ stdcall get_child_socket_fd()
4139 +@ stdcall store_handle_pair(long long)
4140 +@ stdcall search_handle_pair(long)
4141 +@ stdcall delete_handle_pair(ptr)
4142 +@ stdcall server_abort_thread(long)
4143 diff -urN wine-1.0/dlls/ntdll/om.c wine-1.0-uk/dlls/ntdll/om.c
4144 --- wine-1.0/dlls/ntdll/om.c 2008-06-17 22:07:31.000000000 +0800
4145 +++ wine-1.0-uk/dlls/ntdll/om.c 2009-08-19 10:22:52.000000000 +0800
4147 #include "winternl.h"
4148 #include "ntdll_misc.h"
4149 #include "wine/server.h"
4150 +#ifdef UNIFIED_KERNEL
4151 +#include "handle.h"
4154 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
4157 TRACE("(%p,0x%08x,%p,0x%08x,%p): stub\n",
4158 handle, info_class, ptr, len, used_len);
4160 +#ifndef UNIFIED_KERNEL
4161 if (used_len) *used_len = 0;
4164 @@ -112,6 +116,73 @@
4165 status = STATUS_NOT_IMPLEMENTED;
4169 + if (!IS_UK_HANDLE(handle))
4171 + if (used_len) *used_len = 0;
4173 + switch (info_class)
4175 + case ObjectBasicInformation:
4177 + POBJECT_BASIC_INFORMATION p = (POBJECT_BASIC_INFORMATION)ptr;
4179 + if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
4181 + SERVER_START_REQ( get_object_info )
4183 + req->handle = handle;
4184 + status = wine_server_call( req );
4185 + if (status == STATUS_SUCCESS)
4187 + memset( p, 0, sizeof(*p) );
4188 + p->GrantedAccess = reply->access;
4189 + p->PointerCount = reply->ref_count;
4190 + p->HandleCount = 1; /* at least one */
4191 + if (used_len) *used_len = sizeof(*p);
4197 + case ObjectDataInformation:
4199 + OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
4201 + if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
4203 + SERVER_START_REQ( set_handle_info )
4205 + req->handle = handle;
4208 + status = wine_server_call( req );
4209 + if (status == STATUS_SUCCESS)
4211 + p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
4212 + p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
4213 + if (used_len) *used_len = sizeof(*p);
4220 + FIXME("Unsupported information class %u\n", info_class);
4221 + status = STATUS_NOT_IMPLEMENTED;
4227 + __asm__ __volatile__ (
4228 + "movl $0x86,%%eax\n\t"
4229 + "lea 8(%%ebp),%%edx\n\t"
4239 TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
4240 handle, info_class, ptr, len);
4242 +#ifndef UNIFIED_KERNEL
4245 case ObjectDataInformation:
4246 @@ -154,6 +226,45 @@
4247 status = STATUS_NOT_IMPLEMENTED;
4251 + if (!IS_UK_HANDLE(handle))
4253 + switch (info_class)
4255 + case ObjectDataInformation:
4257 + OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
4259 + if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
4261 + SERVER_START_REQ( set_handle_info )
4263 + req->handle = handle;
4265 + req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
4266 + if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
4267 + if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
4268 + status = wine_server_call( req );
4274 + FIXME("Unsupported information class %u\n", info_class);
4275 + status = STATUS_NOT_IMPLEMENTED;
4281 + __asm__ __volatile__ (
4282 + "movl $0xB9,%%eax\n\t"
4283 + "lea 8(%%ebp),%%edx\n\t"
4293 ACCESS_MASK access, ULONG attributes, ULONG options )
4296 +#ifndef UNIFIED_KERNEL
4297 SERVER_START_REQ( dup_handle )
4299 req->src_process = source_process;
4300 @@ -277,6 +389,45 @@
4305 + if (!IS_UK_HANDLE(source))
4307 + SERVER_START_REQ( dup_handle )
4309 + req->src_process = source_process;
4310 + req->src_handle = source;
4311 + req->dst_process = dest_process;
4312 + req->access = access;
4313 + req->attributes = attributes;
4314 + req->options = options;
4316 + if (!(ret = wine_server_call( req )))
4318 + if (dest) *dest = reply->handle;
4319 + if (reply->closed)
4323 + int fd = server_remove_fd_from_cache( source );
4324 + if (fd != -1) close( fd );
4327 + else if (options & DUPLICATE_CLOSE_SOURCE)
4328 + WARN( "failed to close handle %p in process %p\n", source, source_process );
4335 + __asm__ __volatile__ (
4336 + "movl $0x34,%%eax\n\t"
4337 + "lea 8(%%ebp),%%edx\n\t"
4348 int fd = server_remove_fd_from_cache( Handle );
4350 +#ifndef UNIFIED_KERNEL
4351 SERVER_START_REQ( close_handle )
4353 req->handle = Handle;
4354 @@ -304,6 +456,45 @@
4357 if (fd != -1) close( fd );
4359 + if (!IS_UK_HANDLE(Handle))
4362 + SERVER_START_REQ( close_handle )
4364 + req->handle = Handle;
4365 + ret = wine_server_call( req );
4368 + if (fd != -1) close( fd );
4372 + __asm__ __volatile__ (
4373 + "movl $0x11,%%eax\n\t"
4374 + "lea 8(%%ebp),%%edx\n\t"
4380 + struct handle_pair* pair;
4382 + if ((pair = search_handle_pair(Handle)))
4384 + fd = server_remove_fd_from_cache( pair->wine_handle ); /* FIXME */
4385 + SERVER_START_REQ( close_handle )
4387 + req->handle = pair->wine_handle;
4388 + ret = wine_server_call( req );
4391 + if (fd != -1) close( fd );
4392 + delete_handle_pair(pair);
4404 +#ifndef UNIFIED_KERNEL
4405 if (restart) *context = 0;
4408 @@ -460,6 +652,52 @@
4409 FIXME("multiple entries not implemented\n");
4410 ret = STATUS_NOT_IMPLEMENTED;
4413 + if (!IS_UK_HANDLE(handle))
4415 + if (restart) *context = 0;
4417 + if (single_entry) {
4418 + if (size <= sizeof(*buffer) + 2*sizeof(WCHAR)) return STATUS_BUFFER_OVERFLOW;
4420 + SERVER_START_REQ( get_directory_entry )
4422 + req->handle = handle;
4423 + req->index = *context;
4424 + wine_server_set_reply( req, buffer + 1, size - sizeof(*buffer) - 2*sizeof(WCHAR) );
4425 + if (!(ret = wine_server_call( req )))
4427 + buffer->ObjectName.Buffer = (WCHAR *)(buffer + 1);
4428 + buffer->ObjectName.Length = reply->name_len;
4429 + buffer->ObjectName.MaximumLength = reply->name_len + sizeof(WCHAR);
4430 + buffer->ObjectTypeName.Buffer = (WCHAR *)(buffer + 1) + reply->name_len/sizeof(WCHAR) + 1;
4431 + buffer->ObjectTypeName.Length = wine_server_reply_size( reply ) - reply->name_len;
4432 + buffer->ObjectTypeName.MaximumLength = buffer->ObjectTypeName.Length + sizeof(WCHAR);
4433 + /* make room for the terminating null */
4434 + memmove( buffer->ObjectTypeName.Buffer, buffer->ObjectTypeName.Buffer - 1,
4435 + buffer->ObjectTypeName.Length );
4436 + buffer->ObjectName.Buffer[buffer->ObjectName.Length/sizeof(WCHAR)] = 0;
4437 + buffer->ObjectTypeName.Buffer[buffer->ObjectTypeName.Length/sizeof(WCHAR)] = 0;
4443 + *ret_size = buffer->ObjectName.MaximumLength + buffer->ObjectTypeName.MaximumLength + sizeof(*buffer);
4445 + FIXME("multiple entries not implemented\n");
4446 + ret = STATUS_NOT_IMPLEMENTED;
4449 + __asm__ __volatile__ (
4450 + "movl $0x76,%%eax\n\t"
4451 + "lea 8(%%ebp),%%edx\n\t"
4463 TRACE("(%p,%p,%p)\n", LinkHandle, LinkTarget, ReturnedLength);
4465 +#ifndef UNIFIED_KERNEL
4466 if (!LinkTarget) return STATUS_ACCESS_VIOLATION;
4468 SERVER_START_REQ(query_symlink)
4469 @@ -600,6 +839,33 @@
4474 + if (!IS_UK_HANDLE(LinkHandle))
4476 + if (!LinkTarget) return STATUS_ACCESS_VIOLATION;
4478 + SERVER_START_REQ(query_symlink)
4480 + req->handle = LinkHandle;
4481 + wine_server_set_reply( req, LinkTarget->Buffer, LinkTarget->MaximumLength );
4482 + if (!(ret = wine_server_call( req )))
4484 + LinkTarget->Length = wine_server_reply_size(reply);
4485 + if (ReturnedLength) *ReturnedLength = LinkTarget->Length;
4492 + __asm__ __volatile__ (
4493 + "movl $0x8C,%%eax\n\t"
4494 + "lea 8(%%ebp),%%edx\n\t"
4503 diff -urN wine-1.0/dlls/ntdll/path.c wine-1.0-uk/dlls/ntdll/path.c
4504 --- wine-1.0/dlls/ntdll/path.c 2008-06-17 22:07:31.000000000 +0800
4505 +++ wine-1.0-uk/dlls/ntdll/path.c 2009-08-19 10:13:55.000000000 +0800
4506 @@ -1005,6 +1005,21 @@
4508 if (size && ptr[size - 1] != '\\') ptr[size++] = '\\';
4510 +#ifdef UNIFIED_KERNEL
4511 + if (curdir->DosPath.MaximumLength < (unsigned long)((size + 1) * sizeof(WCHAR))) {
4512 + /* allocate new memory */
4513 + if (curdir->DosPath.Buffer)
4514 + RtlFreeHeap(GetProcessHeap(), 0, curdir->DosPath.Buffer);
4515 + curdir->DosPath.MaximumLength = (size + 1) * sizeof(WCHAR);
4516 + curdir->DosPath.Buffer = RtlAllocateHeap(GetProcessHeap(),
4517 + 0, curdir->DosPath.MaximumLength);
4518 + if (!curdir->DosPath.Buffer)
4525 memcpy( curdir->DosPath.Buffer, ptr, size * sizeof(WCHAR));
4526 curdir->DosPath.Buffer[size] = 0;
4527 curdir->DosPath.Length = size * sizeof(WCHAR);
4528 diff -urN wine-1.0/dlls/ntdll/process.c wine-1.0-uk/dlls/ntdll/process.c
4529 --- wine-1.0/dlls/ntdll/process.c 2008-06-17 22:07:31.000000000 +0800
4530 +++ wine-1.0-uk/dlls/ntdll/process.c 2009-08-19 10:23:24.000000000 +0800
4532 #include "winternl.h"
4533 #include "ntdll_misc.h"
4534 #include "wine/server.h"
4535 +#ifdef UNIFIED_KERNEL
4536 +#include "handle.h"
4539 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
4544 +#ifdef UNIFIED_KERNEL
4547 +NtCreateProcess(OUT PHANDLE ProcessHandle,
4548 + IN ACCESS_MASK DesiredAccess,
4549 + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
4550 + IN HANDLE ParentProcess,
4551 + IN BOOLEAN InheritObjectTable,
4552 + IN HANDLE SectionHandle OPTIONAL,
4553 + IN HANDLE DebugPort OPTIONAL,
4554 + IN HANDLE ExceptionPort OPTIONAL)
4557 + TRACE("DesiredAccess %x, ObjectAttributes %p, name %s, ParentProcess %p, \
4558 + InheritObjectTable %d, SectionHandle %p, DebugPort %p, ExceptionPort %p\n",
4559 + DesiredAccess, ObjectAttributes, ObjectAttributes->ObjectName ?
4560 + debugstr_us(ObjectAttributes->ObjectName) : NULL,
4561 + ParentProcess, InheritObjectTable, SectionHandle, DebugPort, ExceptionPort);
4562 + __asm__ __volatile__ (
4563 + "movl $0x22,%%eax\n\t"
4564 + "lea 8(%%ebp),%%edx\n\t"
4572 /******************************************************************************
4573 * NtTerminateProcess [NTDLL.@]
4575 NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
4578 +#ifndef UNIFIED_KERNEL
4580 SERVER_START_REQ( terminate_process )
4585 if (self) exit( exit_code );
4588 + HANDLE wine_handle;
4590 + if (GetCurrentProcess() != handle) {
4591 + struct handle_pair * pair = search_handle_pair(handle);
4592 + wine_handle = pair->wine_handle;
4594 + wine_handle = handle;
4596 + SERVER_START_REQ( terminate_process )
4598 + req->handle = wine_handle;
4599 + req->exit_code = exit_code;
4600 + ret = wine_server_call( req );
4601 + self = !ret && reply->self;
4605 + /* no return, if handle == 0xffffffff */
4606 + __asm__ __volatile__ (
4607 + "movl $0xD3,%%eax\n\t"
4608 + "lea 8(%%ebp),%%edx\n\t"
4617 OUT PULONG ReturnLength)
4619 NTSTATUS ret = STATUS_SUCCESS;
4620 +#ifndef UNIFIED_KERNEL
4623 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
4624 @@ -340,6 +399,14 @@
4627 if (ReturnLength) *ReturnLength = len;
4629 + __asm__ __volatile__ (
4630 + "movl $0x7D,%%eax\n\t"
4631 + "lea 8(%%ebp),%%edx\n\t"
4641 NTSTATUS ret = STATUS_SUCCESS;
4643 +#ifndef UNIFIED_KERNEL
4644 switch (ProcessInformationClass)
4646 case ProcessAffinityMask:
4647 @@ -396,6 +464,14 @@
4648 ret = STATUS_NOT_IMPLEMENTED;
4652 + __asm__ __volatile__ (
4653 + "movl $0xBA,%%eax\n\t"
4654 + "lea 8(%%ebp),%%edx\n\t"
4666 +#ifndef UNIFIED_KERNEL
4667 SERVER_START_REQ( open_process )
4669 req->pid = HandleToULong(cid->UniqueProcess);
4670 @@ -434,5 +511,34 @@
4671 if (!status) *handle = reply->handle;
4675 + PHANDLE uk_handle = handle;
4676 + HANDLE wine_handle;
4678 + __asm__ __volatile__ (
4679 + "movl $0x5E,%%eax\n\t"
4680 + "lea 8(%%ebp),%%edx\n\t"
4687 + SERVER_START_REQ( open_process )
4689 + req->pid = (process_id_t)cid->UniqueProcess;
4690 + req->access = access;
4691 + req->attributes = attr ? attr->Attributes : 0;
4692 + status = wine_server_call( req );
4695 + wine_handle = reply->handle;
4696 + if (!store_handle_pair(*uk_handle, wine_handle))
4697 + return STATUS_NO_MEMORY;
4705 diff -urN wine-1.0/dlls/ntdll/reg.c wine-1.0-uk/dlls/ntdll/reg.c
4706 --- wine-1.0/dlls/ntdll/reg.c 2008-06-17 22:07:31.000000000 +0800
4707 +++ wine-1.0-uk/dlls/ntdll/reg.c 2009-08-19 10:41:18.000000000 +0800
4709 /* maximum length of a key/value name in bytes (without terminating null) */
4710 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
4712 +#ifdef UNIFIED_KERNEL
4713 +extern NTSTATUS WINAPI
4714 +NtWineService(struct __server_request_info * ReqMsg);
4717 /******************************************************************************
4718 * NtCreateKey [NTDLL.@]
4719 * ZwCreateKey [NTDLL.@]
4721 req->namelen = attr->ObjectName->Length;
4722 wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
4723 if (class) wine_server_add_data( req, class->Buffer, class->Length );
4724 +#ifndef UNIFIED_KERNEL
4725 if (!(ret = wine_server_call( req )))
4727 + if (!(ret = NtWineService(&__req)))
4730 *retkey = reply->hkey;
4731 if (dispos) *dispos = reply->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
4732 @@ -129,7 +138,11 @@
4733 req->access = access;
4734 req->attributes = attr->Attributes;
4735 wine_server_add_data( req, attr->ObjectName->Buffer, len );
4736 +#ifndef UNIFIED_KERNEL
4737 ret = wine_server_call( req );
4739 + ret = NtWineService( req );
4741 *retkey = reply->hkey;
4744 @@ -162,7 +175,11 @@
4745 SERVER_START_REQ( delete_key )
4748 +#ifndef UNIFIED_KERNEL
4749 ret = wine_server_call( req );
4751 + ret = NtWineService( req );
4756 @@ -193,7 +210,11 @@
4759 wine_server_add_data( req, name->Buffer, name->Length );
4760 +#ifndef UNIFIED_KERNEL
4761 ret = wine_server_call( req );
4763 + ret = NtWineService( req );
4768 @@ -230,7 +251,11 @@
4770 req->info_class = info_class;
4771 if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
4772 +#ifndef UNIFIED_KERNEL
4773 if (!(ret = wine_server_call( req )))
4775 + if (!(ret = NtWineService( req )))
4778 LARGE_INTEGER modif;
4780 @@ -445,7 +470,11 @@
4782 req->info_class = info_class;
4783 if (length > fixed_size) wine_server_set_reply( req, ptr, length - fixed_size );
4784 +#ifndef UNIFIED_KERNEL
4785 if (!(ret = wine_server_call( req )))
4787 + if (!(ret = NtWineService( req )))
4790 copy_key_value_info( info_class, info, length, reply->type, reply->namelen,
4791 wine_server_reply_size(reply) - reply->namelen );
4792 @@ -518,7 +547,11 @@
4794 wine_server_add_data( req, name->Buffer, name->Length );
4795 if (length > fixed_size && data_ptr) wine_server_set_reply( req, data_ptr, length - fixed_size );
4796 +#ifndef UNIFIED_KERNEL
4797 if (!(ret = wine_server_call( req )))
4799 + if (!(ret = NtWineService( req )))
4802 copy_key_value_info( info_class, info, length, reply->type,
4803 name->Length, reply->total );
4804 @@ -579,7 +612,11 @@
4805 SERVER_START_REQ( flush_key )
4808 +#ifndef UNIFIED_KERNEL
4809 ret = wine_server_call( req );
4811 + ret = NtWineService( req );
4816 @@ -607,7 +644,11 @@
4817 req->hkey = attr->RootDirectory;
4819 wine_server_add_data(req, attr->ObjectName->Buffer, attr->ObjectName->Length);
4820 +#ifndef UNIFIED_KERNEL
4821 ret = wine_server_call( req );
4823 + ret = NtWineService( req );
4828 @@ -656,7 +697,11 @@
4830 req->subtree = WatchSubtree;
4831 req->filter = CompletionFilter;
4832 +#ifndef UNIFIED_KERNEL
4833 ret = wine_server_call( req );
4835 + ret = NtWineService( req );
4840 @@ -730,7 +775,11 @@
4842 req->hkey = KeyHandle;
4843 req->file = FileHandle;
4844 +#ifndef UNIFIED_KERNEL
4845 ret = wine_server_call( req );
4847 + ret = NtWineService( req );
4852 @@ -776,7 +825,11 @@
4853 req->namelen = name->Length;
4854 wine_server_add_data( req, name->Buffer, name->Length );
4855 wine_server_add_data( req, data, count );
4856 +#ifndef UNIFIED_KERNEL
4857 ret = wine_server_call( req );
4859 + ret = NtWineService( req );
4864 @@ -808,7 +861,11 @@
4865 SERVER_START_REQ( unload_registry )
4867 req->hkey = attr->RootDirectory;
4868 +#ifndef UNIFIED_KERNEL
4869 ret = wine_server_call(req);
4871 + ret = NtWineService( req );
4876 diff -urN wine-1.0/dlls/ntdll/server.c wine-1.0-uk/dlls/ntdll/server.c
4877 --- wine-1.0/dlls/ntdll/server.c 2008-06-17 22:07:31.000000000 +0800
4878 +++ wine-1.0-uk/dlls/ntdll/server.c 2009-08-19 10:22:48.000000000 +0800
4880 #include "wine/server.h"
4881 #include "wine/debug.h"
4882 #include "ntdll_misc.h"
4883 +#include "handle.h"
4886 WINE_DEFAULT_DEBUG_CHANNEL(server);
4888 @@ -108,6 +110,23 @@
4889 static void server_connect_error( const char *serverdir ) __attribute__((noreturn));
4892 +#ifdef UNIFIED_KERNEL
4894 +NtWineService(struct __server_request_info * ReqMsg)
4898 + __asm__ __volatile__ (
4899 + "movl $0xe8,%%eax\n\t"
4900 + "lea 8(%%ebp),%%edx\n\t"
4909 /* die on a fatal error; use only during initialization */
4910 static void fatal_error( const char *err, ... )
4914 void server_exit_thread( int status )
4916 +#ifndef UNIFIED_KERNEL
4917 struct wine_pthread_thread_info info;
4920 @@ -173,20 +193,57 @@
4923 pthread_functions.exit_thread( &info );
4927 + RtlAcquirePebLock();
4928 + RemoveEntryList( &NtCurrentTeb()->TlsLinks );
4929 + RtlReleasePebLock();
4931 + RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots ); /* HCZ */
4932 + RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots ); /* HCZ */
4934 + fds[0] = ntdll_get_thread_data()->wait_fd[0];
4935 + fds[1] = ntdll_get_thread_data()->wait_fd[1];
4936 + fds[2] = ntdll_get_thread_data()->reply_fd;
4937 + fds[3] = ntdll_get_thread_data()->request_fd;
4944 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4946 + NtTerminateThread(GetCurrentThread(),0);
4951 /***********************************************************************
4952 * server_abort_thread
4954 +#ifndef UNIFIED_KERNEL
4955 void server_abort_thread( int status )
4957 +int server_abort_thread( int status )
4960 +#ifndef UNIFIED_KERNEL
4961 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4963 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4965 close( ntdll_get_thread_data()->wait_fd[0] );
4966 close( ntdll_get_thread_data()->wait_fd[1] );
4967 close( ntdll_get_thread_data()->reply_fd );
4968 close( ntdll_get_thread_data()->request_fd );
4969 +#ifndef UNIFIED_KERNEL
4970 pthread_functions.abort_thread( status );
4973 + return NtTerminateThread(GetCurrentThread(), status);
4978 @@ -323,10 +380,18 @@
4982 +#ifndef UNIFIED_KERNEL
4983 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, &old_set );
4985 + sigprocmask( SIG_BLOCK, &server_block_set, &old_set );
4987 ret = send_request( req );
4988 if (!ret) ret = wait_reply( req );
4989 +#ifndef UNIFIED_KERNEL
4990 pthread_functions.sigprocmask( SIG_SETMASK, &old_set, NULL );
4992 + sigprocmask( SIG_SETMASK, &old_set, NULL );
4997 @@ -336,7 +401,11 @@
4999 void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset )
5001 +#ifndef UNIFIED_KERNEL
5002 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, sigset );
5004 + sigprocmask( SIG_BLOCK, &server_block_set, sigset );
5006 RtlEnterCriticalSection( cs );
5009 @@ -347,7 +416,11 @@
5010 void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset )
5012 RtlLeaveCriticalSection( cs );
5013 +#ifndef UNIFIED_KERNEL
5014 pthread_functions.sigprocmask( SIG_SETMASK, sigset, NULL );
5016 + sigprocmask( SIG_SETMASK, sigset, NULL );
5021 @@ -459,7 +532,11 @@
5022 server_protocol_perror("recvmsg");
5024 /* the server closed the connection; time to die... */
5025 +#ifndef UNIFIED_KERNEL
5026 server_abort_thread(0);
5028 + return server_abort_thread(0);
5033 @@ -475,16 +552,35 @@
5036 #define FD_CACHE_BLOCK_SIZE (65536 / sizeof(struct fd_cache_entry))
5037 +#ifdef UNIFIED_KERNEL
5038 +#define FD_CACHE_ENTRIES 256
5040 #define FD_CACHE_ENTRIES 128
5043 static struct fd_cache_entry *fd_cache[FD_CACHE_ENTRIES];
5044 static struct fd_cache_entry fd_cache_initial_block[FD_CACHE_BLOCK_SIZE];
5046 static inline unsigned int handle_to_index( obj_handle_t handle, unsigned int *entry )
5048 +#ifdef UNIFIED_KERNEL
5049 + unsigned long idx;
5051 + if (IS_UK_HANDLE(handle))
5052 + idx = (((unsigned long)UK_HANDLE_TO_HANDLE(handle)) >> 2) - 1;
5054 + idx = ((unsigned long)handle >> 2) - 1;
5055 + *entry = idx / FD_CACHE_BLOCK_SIZE;
5056 + if (*entry > FD_CACHE_ENTRIES / 2)
5057 + *entry = FD_CACHE_ENTRIES;
5058 + if (IS_UK_HANDLE(handle))
5059 + *entry += FD_CACHE_ENTRIES / 2;
5060 + return idx % FD_CACHE_BLOCK_SIZE;
5062 unsigned long idx = ((unsigned long)handle >> 2) - 1;
5063 *entry = idx / FD_CACHE_BLOCK_SIZE;
5064 return idx % FD_CACHE_BLOCK_SIZE;
5070 fd = get_cached_fd( handle, type, &access, options );
5071 if (fd != -1) goto done;
5073 +#ifndef UNIFIED_KERNEL
5074 SERVER_START_REQ( get_handle_fd )
5076 req->handle = handle;
5077 @@ -604,6 +701,42 @@
5082 + SERVER_START_REQ( get_handle_fd )
5084 + req->handle = handle;
5085 + if (!IS_UK_HANDLE(handle))
5086 + ret = wine_server_call( req );
5088 + ret = NtWineService( req );
5092 + if (type) *type = reply->type;
5093 + if (options) *options = reply->options;
5094 + access = reply->access;
5095 + if (!IS_UK_HANDLE(handle))
5096 + fd = receive_fd( &fd_handle );
5102 + if (!IS_UK_HANDLE(handle)) {
5103 + assert( fd_handle == handle );
5104 + *needs_close = (reply->removable ||
5105 + !add_fd_to_cache( handle, fd, reply->type,
5106 + reply->access, reply->options ));
5108 + *needs_close = FALSE;
5109 + add_fd_to_cache( handle, fd, reply->type, reply->access, reply->options);
5112 + else ret = STATUS_TOO_MANY_OPENED_FILES;
5119 server_leave_uninterrupted_section( &fd_cache_section, &sigset );
5120 @@ -959,7 +1092,11 @@
5121 sigaddset( &server_block_set, SIGUSR1 );
5122 sigaddset( &server_block_set, SIGUSR2 );
5123 sigaddset( &server_block_set, SIGCHLD );
5124 +#ifndef UNIFIED_KERNEL
5125 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
5127 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
5130 /* receive the first thread request fd on the main socket */
5131 ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle );
5132 @@ -1049,6 +1186,10 @@
5133 req->reply_fd = reply_pipe[1];
5134 req->wait_fd = ntdll_get_thread_data()->wait_fd[1];
5135 req->debug_level = (TRACE_ON(server) != 0);
5136 +#ifdef UNIFIED_KERNEL
5137 + req->pid = (int) NtCurrentTeb()->RealClientId.UniqueProcess;
5138 + req->tid = (int) NtCurrentTeb()->RealClientId.UniqueThread;
5140 ret = wine_server_call( req );
5141 NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
5142 NtCurrentTeb()->ClientId.UniqueThread = ULongToHandle(reply->tid);
5143 diff -urN wine-1.0/dlls/ntdll/sync.c wine-1.0-uk/dlls/ntdll/sync.c
5144 --- wine-1.0/dlls/ntdll/sync.c 2008-06-17 22:07:31.000000000 +0800
5145 +++ wine-1.0-uk/dlls/ntdll/sync.c 2009-08-19 10:44:09.000000000 +0800
5147 #include "wine/server.h"
5148 #include "wine/debug.h"
5149 #include "ntdll_misc.h"
5150 +#ifdef UNIFIED_KERNEL
5151 +#include "handle.h"
5154 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
5157 IN LONG InitialCount,
5158 IN LONG MaximumCount )
5160 +#ifndef UNIFIED_KERNEL
5161 DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
5163 struct object_attributes objattr;
5164 @@ -176,6 +180,16 @@
5167 NTDLL_free_struct_sd( sd );
5171 + __asm__ __volatile__ (
5172 + "movl $0x25,%%eax\n\t"
5173 + "lea 8(%%ebp),%%edx\n\t"
5182 IN ACCESS_MASK access,
5183 IN const OBJECT_ATTRIBUTES *attr )
5185 +#ifndef UNIFIED_KERNEL
5186 DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
5189 @@ -202,6 +217,16 @@
5190 *SemaphoreHandle = reply->handle;
5196 + __asm__ __volatile__ (
5197 + "movl $0x62,%%eax\n\t"
5198 + "lea 8(%%ebp),%%edx\n\t"
5207 NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous )
5210 +#ifndef UNIFIED_KERNEL
5211 SERVER_START_REQ( release_semaphore )
5213 req->handle = handle;
5214 @@ -236,6 +262,14 @@
5219 + __asm__ __volatile__ (
5220 + "movl $0x9E,%%eax\n\t"
5221 + "lea 8(%%ebp),%%edx\n\t"
5230 IN BOOLEAN InitialOwner)
5233 +#ifndef UNIFIED_KERNEL
5234 DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
5235 struct security_descriptor *sd = NULL;
5236 struct object_attributes objattr;
5237 @@ -448,6 +483,14 @@
5240 NTDLL_free_struct_sd( sd );
5242 + __asm__ __volatile__ (
5243 + "movl $0x1E,%%eax\n\t"
5244 + "lea 8(%%ebp),%%edx\n\t"
5253 IN const OBJECT_ATTRIBUTES* attr )
5256 +#ifndef UNIFIED_KERNEL
5257 DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
5259 if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG;
5260 @@ -475,6 +519,14 @@
5261 *MutantHandle = reply->handle;
5265 + __asm__ __volatile__ (
5266 + "movl $0x5C,%%eax\n\t"
5267 + "lea 8(%%ebp),%%edx\n\t"
5279 +#ifndef UNIFIED_KERNEL
5280 SERVER_START_REQ( release_mutex )
5282 req->handle = handle;
5283 @@ -493,6 +546,14 @@
5284 if (prev_count) *prev_count = reply->prev_count;
5288 + __asm__ __volatile__ (
5289 + "movl $0x9D,%%eax\n\t"
5290 + "lea 8(%%ebp),%%edx\n\t"
5298 @@ -755,7 +816,11 @@
5299 server_protocol_perror("wakeup read");
5301 /* the server closed the connection; time to die... */
5302 +#ifndef UNIFIED_KERNEL
5303 server_abort_thread(0);
5305 + return server_abort_thread(0);
5310 @@ -1016,6 +1081,7 @@
5311 BOOLEAN wait_all, BOOLEAN alertable,
5312 const LARGE_INTEGER *timeout )
5314 +#ifndef UNIFIED_KERNEL
5315 UINT flags = SELECT_INTERRUPTIBLE;
5317 if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
5318 @@ -1023,6 +1089,32 @@
5319 if (wait_all) flags |= SELECT_ALL;
5320 if (alertable) flags |= SELECT_ALERTABLE;
5321 return NTDLL_wait_for_multiple_objects( count, handles, flags, timeout, 0 );
5323 + NTSTATUS ret = WAIT_TIMEOUT;
5324 + UINT flags = SELECT_INTERRUPTIBLE;
5326 + if (!count || count > MAXIMUM_WAIT_OBJECTS)
5327 + return STATUS_INVALID_PARAMETER_1;
5329 + if (wait_all) flags |= SELECT_ALL;
5330 + if (alertable) flags |= SELECT_ALERTABLE;
5332 + if (!IS_UK_HANDLE(*handles)) {
5333 + ret = NTDLL_wait_for_multiple_objects( count, handles, flags, timeout, 0);
5337 + __asm__ __volatile__ (
5338 + "movl $0xDE,%%eax\n\t"
5339 + "lea 8(%%ebp),%%edx\n\t"
5343 + } while (-EINTR == ret);
5351 diff -urN wine-1.0/dlls/ntdll/thread.c wine-1.0-uk/dlls/ntdll/thread.c
5352 --- wine-1.0/dlls/ntdll/thread.c 2008-06-17 22:07:31.000000000 +0800
5353 +++ wine-1.0-uk/dlls/ntdll/thread.c 2009-08-19 10:23:18.000000000 +0800
5355 #include "ntdll_misc.h"
5356 #include "ddk/wdm.h"
5357 #include "wine/exception.h"
5358 +#ifdef UNIFIED_KERNEL
5359 +#include <assert.h>
5360 +#include "handle.h"
5365 +#include <unistd.h>
5367 +#define PTHREAD_KEYS_MAX 1024
5368 +#define PTHREAD_KEY_2NDLEVEL_SIZE 32
5369 +#define PTHREAD_KEY_1STLEVEL_SIZE \
5370 + ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
5371 + / PTHREAD_KEY_2NDLEVEL_SIZE)
5373 +typedef unsigned char bool;
5377 + void *tcb; /* Pointer to the TCB. Not necessarily the
5378 + thread descriptor used by libpthread. */
5381 + void *self; /* Pointer to the thread descriptor. */
5382 + int multiple_threads;
5383 + uintptr_t sysinfo;
5384 + uintptr_t stack_guard;
5385 + uintptr_t pointer_guard;
5388 +typedef struct list_head
5390 + struct list_head *next;
5391 + struct list_head *prev;
5394 +typedef int lll_lock_t;
5395 +typedef unsigned long long int hp_timing_t;
5397 +struct robust_list_head
5400 + long int futex_offset;
5401 + void *list_op_pending;
5404 +/* Thread descriptor data structure. */
5409 + /* This overlaps the TCB as used for TLS without threads (see tls.h). */
5411 + /* This extra padding has no special purpose, and this structure layout
5412 + is private and subject to change without affecting the official ABI.
5413 + We just have it here in case it might be convenient for some
5414 + implementation-specific instrumentation hack or suchlike. */
5415 + void *__padding[16];
5418 + /* This descriptor's link on the `stack_used' or `__stack_user' list. */
5421 + /* Thread ID - which is also a 'is this thread descriptor (and
5422 + therefore stack) used' flag. */
5425 + /* Process ID - thread group ID in kernel speak. */
5428 + /* List of robust mutexes the thread is holding. */
5431 + __pthread_slist_t robust_list; */
5432 + struct robust_list_head robust_head;
5435 + /* List of cleanup buffers. */
5436 + /* struct _pthread_cleanup_buffer *cleanup; */
5439 + /* Unwind information. */
5440 + /* struct pthread_unwind_buf *cleanup_jmp_buf; */
5441 + void *cleanup_jmp_buf;
5443 + /* Flags determining processing of cancellation. */
5444 + int cancelhandling;
5446 + /* Flags. Including those copied from the thread attribute. */
5449 + /* We allocate one block of references here. This should be enough
5450 + to avoid allocating any memory dynamically for most applications. */
5451 + struct pthread_key_data
5453 + /* Sequence number. We use uintptr_t to not require padding on
5454 + 32- and 64-bit machines. On 64-bit machines it helps to avoid
5458 + /* Data pointer. */
5460 + } specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
5462 + /* Two-level array for the thread-specific data. */
5463 + struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
5465 + /* Flag which is set when specific data is set. */
5466 + bool specific_used;
5468 + /* True if events must be reported. */
5469 + bool report_events;
5471 + /* True if the user provided the stack. */
5474 + /* True if thread must stop at startup time. */
5475 + bool stopped_start;
5477 + /* The parent's cancel handling at the time of the pthread_create
5478 + call. This might be needed to undo the effects of a cancellation. */
5479 + int parent_cancelhandling;
5481 + /* Lock to synchronize access to the descriptor. */
5484 + /* Lock for synchronizing setxid calls. */
5485 + lll_lock_t setxid_futex;
5487 + /* Offset of the CPU clock at start thread start time. */
5488 + hp_timing_t cpuclock_offset;
5490 + /* If the thread waits to join another one the ID of the latter is
5493 + In case a thread is detached this field contains a pointer of the
5494 + TCB if the thread itself. This is something which cannot happen
5495 + in normal operation. */
5496 + struct pthread *joinid;
5498 + /* The result of the thread function. */
5501 + /* Scheduling parameters for the new thread. */
5502 + struct sched_param schedparam;
5505 + /* Start position of the code to be executed and the argument passed
5506 + to the function. */
5507 + void *(*start_routine) (void *);
5510 + /* Debug state. */
5511 + /* td_eventbuf_t eventbuf; */
5512 + char eventbuf[16];
5514 + /* Next descriptor with a pending event. */
5515 + struct pthread *nextevent;
5517 + /* Machine-specific unwind info. */
5518 + /* struct _Unwind_Exception exc; */
5521 + /* If nonzero pointer to area allocated for the stack and its
5524 + size_t stackblock_size;
5525 + /* Size of the included guard area. */
5527 + /* This is what the user specified and what we will report. */
5528 + size_t reported_guardsize;
5530 + /* Thread Priority Protection data. */
5531 + /* struct priority_protection_data *tpp; */
5534 + /* Resolver state. */
5535 + /* struct __res_state res; */
5537 +} __attribute ((aligned(16)));
5539 +static inline void set_pthread_tid(struct pthread *pthread, pid_t tid)
5541 + pthread->tid = tid;
5546 WINE_DEFAULT_DEBUG_CHANNEL(thread);
5547 WINE_DECLARE_DEBUG_CHANNEL(relay);
5549 static RTL_BITMAP tls_bitmap;
5550 static RTL_BITMAP tls_expansion_bitmap;
5551 static RTL_BITMAP fls_bitmap;
5552 +#ifndef UNIFIED_KERNEL
5553 static LIST_ENTRY tls_links;
5555 +LIST_ENTRY tls_links;
5556 +#define ROUNDUP(a, b) ((((a) + (b) - 1)/(b))*(b))
5558 +#define PAGE_SIZE 0x1000
5560 +#define DEFAULT_STACK_SIZE 0x200000
5561 +#define DEFAULT_GUARD_SIZE 0x1000
5562 +#define DEFAULT_COMMIT_SIZE (32 * PAGE_SIZE)
5564 +#define USER_CS (0x18 + 0x3)
5565 +#define USER_DS (0x20 + 0x3)
5566 +#define TEB_SELECTOR (0x38 + 0x3)
5568 +extern char **environ;
5569 +extern void ProcessStartForward(unsigned long start_address, void *peb);
5571 static size_t sigstack_total_size;
5572 static ULONG sigstack_zero_bits;
5574 @@ -160,7 +365,11 @@
5576 * Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
5578 +#ifndef UNIFIED_KERNEL
5579 static NTSTATUS init_user_process_params( SIZE_T info_size, HANDLE *exe_file )
5581 +NTSTATUS init_user_process_params( SIZE_T info_size, HANDLE *exe_file )
5590 +#ifndef UNIFIED_KERNEL
5591 /***********************************************************************
5594 @@ -451,6 +661,50 @@
5596 call_thread_func( func, arg );
5599 +void start_thread(ULONG unknown1, ULONG unknown2, ULONG unknown3)
5601 + TEB *teb = NtCurrentTeb();
5602 + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
5603 + struct debug_info debug_info;
5604 + struct pthread *pthread;
5606 + asm volatile ("movl %%gs:0x8, %0" : "=r"(pthread));
5607 + set_pthread_tid(pthread, gettid());
5609 + thread_data->debug_info = &debug_info;
5610 + debug_info.str_pos = debug_info.strings;
5611 + debug_info.out_pos = debug_info.output;
5613 + thread_data->fs = 0;
5614 + asm("mov %%fs, %0\n" : "=m"(thread_data->fs));
5617 + server_init_thread(getpid(), gettid(), NULL );
5618 + RtlAcquirePebLock();
5619 + InsertHeadList( &tls_links, &teb->TlsLinks );
5620 + RtlReleasePebLock();
5622 + /* NOTE: Windows does not have an exception handler around the call to
5623 + * the thread attach. We do for ease of debugging */
5624 + if (unhandled_exception_filter)
5628 + MODULE_DllThreadAttach( NULL );
5630 + __EXCEPT(unhandled_exception_filter)
5632 + NtTerminateThread( GetCurrentThread(), GetExceptionCode() );
5637 + MODULE_DllThreadAttach( NULL );
5644 /***********************************************************************
5645 @@ -568,7 +822,11 @@
5647 info->pthread_info.stack_base = NULL;
5648 info->pthread_info.stack_size = stack_reserve;
5649 +#ifndef UNIFIED_KERNEL
5650 info->pthread_info.entry = start_thread;
5652 + info->pthread_info.entry = (void *)start_thread;
5654 info->entry_point = start;
5655 info->entry_arg = param;
5657 @@ -598,6 +856,601 @@
5661 +#ifdef UNIFIED_KERNEL
5663 +NtCreateThread(OUT PHANDLE ThreadHandle,
5664 + IN ACCESS_MASK DesiredAccess,
5665 + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
5666 + IN HANDLE ProcessHandle,
5667 + OUT PCLIENT_ID ClientId,
5668 + IN PCONTEXT ThreadContext,
5669 + IN PINITIAL_TEB InitialTeb,
5670 + IN BOOLEAN CreateSuspended)
5673 + __asm__ __volatile__ (
5674 + "movl $0x27,%%eax\n\t"
5675 + "lea 8(%%ebp),%%edx\n\t"
5682 +VOID RtlRosR32AttribsToNativeAttribs(OUT OBJECT_ATTRIBUTES * NativeAttribs,
5683 + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL)
5685 + NativeAttribs->Length = sizeof(*NativeAttribs);
5686 + NativeAttribs->ObjectName = NULL;
5687 + NativeAttribs->RootDirectory = NULL;
5688 + NativeAttribs->Attributes = 0;
5689 + NativeAttribs->SecurityQualityOfService = NULL;
5691 + if(Ros32Attribs && Ros32Attribs->nLength >= sizeof(*Ros32Attribs)) {
5692 + NativeAttribs->SecurityDescriptor = Ros32Attribs->lpSecurityDescriptor;
5694 + if(Ros32Attribs->bInheritHandle)
5695 + NativeAttribs->Attributes |= OBJ_INHERIT;
5697 + NativeAttribs->SecurityDescriptor = NULL;
5700 +NTSTATUS NTAPI RtlpRosGetStackLimits(IN PINITIAL_TEB InitialTeb,
5701 + OUT PVOID * StackBase,
5702 + OUT PVOID * StackLimit)
5704 + /* fixed-size stack */
5705 + if(InitialTeb->StackBase && InitialTeb->StackLimit) {
5706 + *StackBase = InitialTeb->StackBase;
5707 + *StackLimit = InitialTeb->StackLimit;
5708 + } else if(InitialTeb->StackCommit && InitialTeb->StackCommitMax) { /* expandable stack */
5709 + *StackBase = InitialTeb->StackCommit;
5710 + *StackLimit = InitialTeb->StackCommitMax;
5711 + } else { /* can't determine the type of stack: failure */
5712 + return STATUS_BAD_INITIAL_STACK;
5716 + return STATUS_SUCCESS;
5719 +NTSTATUS NTAPI RtlpRosValidateLinearUserStack(IN PVOID StackBase,
5720 + IN PVOID StackLimit,
5721 + IN BOOLEAN Direction)
5723 + /* the stack has a null or negative (relatively to its direction) length */
5724 + if (StackBase == StackLimit || (Direction ^ ((PCHAR)StackBase < (PCHAR)StackLimit)))
5725 + return STATUS_BAD_INITIAL_STACK;
5728 + return STATUS_SUCCESS;
5733 +RtlRosInitializeContext(IN HANDLE ProcessHandle,
5734 + OUT PCONTEXT Context,
5735 + IN PVOID BaseStartAddress,
5736 + IN PINITIAL_TEB InitialTeb,
5737 + IN ULONG_PTR StartAddress,
5738 + IN ULONG_PTR Parameter)
5740 + static PVOID spRetAddr = (PVOID)0xDEADBEEF;
5743 + NTSTATUS nErrCode;
5745 + PVOID pStackLimit;
5746 + size_t ReserveSize = 3 * sizeof(ULONG_PTR);
5748 + /* Intel x86: linear top-down stack, all parameters passed on the stack */
5749 + /* get the stack base and limit */
5750 + nErrCode = RtlpRosGetStackLimits(InitialTeb, &pStackBase, &pStackLimit);
5756 + /* validate the stack */
5757 + nErrCode = RtlpRosValidateLinearUserStack(pStackBase, pStackLimit, FALSE);
5763 + /* too many parameters */
5764 + if((SIZE_T)((ULONG_PTR)pStackBase - (ULONG_PTR)pStackLimit) < ReserveSize)
5765 + return STATUS_STACK_OVERFLOW;
5767 + memset(Context, 0, sizeof(CONTEXT));
5769 + /* initialize the context */
5770 + Context->ContextFlags = CONTEXT_FULL;
5772 + if(!BaseStartAddress)
5773 + Context->Eip = (ULONG_PTR)ProcessStartForward;
5775 + Context->Eip = (ULONG_PTR)BaseStartAddress;
5777 + Context->SegGs = USER_DS;
5778 + Context->SegFs = TEB_SELECTOR;
5779 + Context->SegEs = USER_DS;
5780 + Context->SegDs = USER_DS;
5781 + Context->SegCs = USER_CS;
5782 + Context->SegSs = USER_DS;
5783 + Context->Esp = (ULONG_PTR)pStackBase - ReserveSize;
5784 + /* FIXME: use this value for eflag temporarily */
5785 + Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
5787 + /* write the parameter */
5788 + nErrCode = NtWriteVirtualMemory(ProcessHandle,
5789 + ((PUCHAR)pStackBase) - sizeof(ULONG_PTR),
5790 + (void *)&Parameter,
5791 + sizeof(Parameter),
5798 + /* write the parameter */
5799 + nErrCode = NtWriteVirtualMemory(ProcessHandle,
5800 + ((PUCHAR)pStackBase) - 2 * sizeof(ULONG_PTR),
5801 + (void *)&StartAddress,
5802 + sizeof(StartAddress),
5809 + /* write the return address */
5810 + return NtWriteVirtualMemory(ProcessHandle,
5811 + ((PUCHAR)pStackBase) - ReserveSize,
5813 + sizeof(spRetAddr),
5817 +NTSTATUS NTAPI RtlRosDeleteStack(IN HANDLE ProcessHandle,
5818 + IN PINITIAL_TEB InitialTeb)
5820 + PVOID pStackLowest = NULL;
5823 + if(InitialTeb->StackLimit)
5824 + pStackLowest = InitialTeb->StackLimit;
5825 + else if(InitialTeb->StackReserved)
5826 + pStackLowest = InitialTeb->StackReserved;
5828 + /* free the stack, if it was allocated */
5830 + return NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
5832 + return STATUS_SUCCESS;
5835 +NTSTATUS NTAPI RtlRosCreateStack(IN HANDLE ProcessHandle,
5836 + OUT PINITIAL_TEB InitialTeb,
5837 + IN LONG StackZeroBits,
5838 + IN OUT PULONG StackReserve OPTIONAL,
5839 + IN OUT PULONG StackCommit OPTIONAL)
5841 + NTSTATUS nErrCode;
5842 + ULONG_PTR StackSize = DEFAULT_STACK_SIZE;
5844 + /* FIXME: ignore the StackReserve and the StackCommit that user thread need */
5846 + /* FIXME: this code assumes a stack growing downwards */
5847 + /* expandable stack */
5849 + InitialTeb->StackBase = NULL;
5850 + InitialTeb->StackReserved = NULL;
5852 + nErrCode = NtAllocateVirtualMemory(ProcessHandle,
5853 + &InitialTeb->StackBase,
5855 + (SIZE_T *)&StackSize,
5856 + MEM_RESERVE | MEM_COMMIT,
5862 + InitialTeb->StackLimit = InitialTeb->StackBase;
5863 + InitialTeb->StackBase = (PVOID)((unsigned long)InitialTeb->StackBase + StackSize);
5866 + return STATUS_SUCCESS;
5868 + /* deallocate the stack */
5869 + RtlRosDeleteStack(ProcessHandle, InitialTeb);
5877 +extern ElfW(auxv_t) *auxvec;
5878 +extern size_t auxvec_len;
5879 +NTSTATUS NTAPI RtlRosInitializeStack(IN HANDLE ProcessHandle,
5880 + OUT PINITIAL_TEB InitialTeb)
5882 + int envc = 0, argc = 0;
5883 + int in_app_name = 0;
5885 + unsigned long size, size_out;
5886 + char **envp = environ, **tmp, **argv = NULL;
5887 + char *last_env = NULL;
5888 + char *child_stack_start, *child_env, *child_argv;
5889 + void *stack, *stack_u = NULL;
5890 + unsigned long env_start, env_end, delta;
5891 + char *c, *p = NULL, *cmd_line = NULL;
5893 + PWCHAR cmd_line_w = NULL, wc;
5894 + PWCHAR app_name_w = NULL;
5896 + RTL_USER_PROCESS_PARAMETERS child_ppb;
5899 + ret = NtReadVirtualMemory(ProcessHandle,
5900 + (PVOID)0x7ffdf000UL,
5901 + (PVOID)&child_peb,
5907 + ret = NtReadVirtualMemory(ProcessHandle,
5908 + (PVOID)child_peb.ProcessParameters,
5909 + (PVOID)&child_ppb,
5910 + sizeof(RTL_USER_PROCESS_PARAMETERS),
5915 + cmd_line_w = (PWCHAR)malloc(child_ppb.CommandLine.MaximumLength);
5916 + cmd_addr =(PVOID)((unsigned long)child_ppb.CommandLine.Buffer);
5917 + if((unsigned long)cmd_addr < (unsigned long)child_peb.ProcessParameters){
5918 + cmd_addr = (PVOID)((unsigned long)child_ppb.CommandLine.Buffer
5919 + + (unsigned long)child_peb.ProcessParameters);
5922 + ret = NtReadVirtualMemory(ProcessHandle,
5924 + (PVOID)cmd_line_w,
5925 + child_ppb.CommandLine.MaximumLength,
5930 + size /= sizeof(WCHAR);
5931 + c = cmd_line = (char *)malloc(size + 256);
5932 + for (wc = cmd_line_w; wc < cmd_line_w + size; wc++) {
5934 + if (in_app_name > 1) {
5935 + *c++ = (unsigned char)*wc;
5937 + if (*wc == (WCHAR)'"') {
5939 + app_name_w = wc + 1;
5941 + UNICODE_STRING nt_name;
5942 + ANSI_STRING unix_name = {0, 0, NULL};
5944 + /* change NT file name to Linux name */
5946 + if (!RtlDosPathNameToNtPathName_U(app_name_w, &nt_name, NULL, NULL))
5948 + if (wine_nt_to_unix_file_name(&nt_name, &unix_name, FILE_OPEN, FALSE)) {
5949 + RtlFreeUnicodeString(&nt_name);
5952 + memcpy(cmd_line, unix_name.Buffer, unix_name.Length);
5953 + cmd_line[unix_name.Length] = 0;
5954 + c += unix_name.Length + 1;
5956 + RtlFreeAnsiString(&unix_name);
5961 + *c = (unsigned char)*wc;
5968 + argv = (char **)malloc(size * sizeof(char *));
5969 + argv[argc++] = cmd_line;
5972 + while ((c = strchr(p, ' '))) {
5974 + if (p != cmd_line)
5979 + argv[argc] = NULL;
5981 + env_start = (unsigned long)*envp;
5987 + /* envp --> auxvec, envp - 1 --> 0 */
5988 + env_end = (unsigned long)*envp;
5989 + if (strncmp(*envp, "_=", 2))
5990 + env_end += strlen((PVOID)env_end) + 1;
5992 + last_env = (char *)malloc(strlen(argv[0]) + 2 + 1);
5993 + sprintf(last_env, "_=%s", argv[0]);
5997 + stack_u = malloc(DEFAULT_COMMIT_SIZE + PAGE_SIZE);
5998 + stack = (void *)(((unsigned long)stack_u + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
5999 + p =(char *)((unsigned long)stack + DEFAULT_COMMIT_SIZE - sizeof(void *));
6002 + p -= strlen(*argv) + 1;
6003 + memcpy(p, *argv, strlen(*argv) + 1);
6005 + /* copy environ */
6007 + size = strlen(last_env) + 1;
6009 + memcpy(p, last_env, size);
6011 + size = env_end - env_start;
6013 + memcpy(p, (PVOID)env_start, size);
6016 + /* copy cmd line */
6018 + while (--i >= 0) {
6019 + p -= strlen(argv[i]) + 1;
6020 + memcpy(p, argv[i], strlen(argv[i]) + 1);
6023 + size = auxvec_len;
6026 + size = (argc + 1 + envc + 1 + 1) * sizeof(unsigned long);
6027 + p = (char *)(((unsigned long)p - size) & ~15);
6028 + child_stack_start = p;
6029 + p = child_stack_start + size;
6030 + memcpy(p, (void *)auxvec, auxvec_len);
6031 + p = child_stack_start;
6037 + while (--i >= 0) {
6038 + *(unsigned long *)p = (unsigned long)c;
6039 + c += strlen(c) + 1;
6040 + p += sizeof(unsigned long);
6043 + p += sizeof(int *);
6046 + while (--i >= 0) {
6047 + *(unsigned long *)p = (unsigned long)c;
6048 + c += strlen(c) + 1;
6049 + p += sizeof(unsigned long);
6054 + InitialTeb->StackReserved = InitialTeb->StackBase;
6055 + size = DEFAULT_COMMIT_SIZE - (child_stack_start - (char *)stack);
6056 + InitialTeb->StackBase = (PVOID)((unsigned long)InitialTeb->StackBase - size);
6058 + delta = (unsigned long)InitialTeb->StackBase - (unsigned long)child_stack_start;
6059 + argc = *(int *)child_stack_start;
6060 + tmp = (char **)((int *)child_stack_start + 1);
6062 + for (i = 0; i < argc; i++)
6065 + envp = tmp + argc + 1;
6072 + ret = NtWriteVirtualMemory(ProcessHandle,
6073 + InitialTeb->StackBase,
6074 + child_stack_start,
6096 +extern NTSTATUS WINAPI NtResumeThread( HANDLE handle, PULONG count );
6097 +extern void *_dl_allocate_tls(void *);
6100 +RtlRosCreateUserThread(IN HANDLE ProcessHandle,
6101 + IN POBJECT_ATTRIBUTES ObjectAttributes,
6102 + IN BOOLEAN CreateSuspended,
6103 + IN LONG StackZeroBits,
6104 + IN OUT PULONG StackReserve OPTIONAL,
6105 + IN OUT PULONG StackCommit OPTIONAL,
6106 + IN PVOID BaseStartAddress,
6107 + OUT PHANDLE ThreadHandle OPTIONAL,
6108 + OUT PCLIENT_ID ClientId OPTIONAL,
6109 + IN ULONG_PTR StartAddress,
6110 + IN ULONG_PTR Parameter)
6112 + INITIAL_TEB usUserInitialTeb;
6113 + CONTEXT ctxInitialContext;
6114 + NTSTATUS nErrCode;
6115 + int request_pipe[2];
6116 + struct ntdll_thread_data *thread_data;
6117 + THREAD_BASIC_INFORMATION thread_info;
6119 + HANDLE wine_handle;
6126 + /* allocate the stack for the thread */
6127 + nErrCode = RtlRosCreateStack(ProcessHandle,
6128 + &usUserInitialTeb,
6137 + if (!BaseStartAddress) {
6138 + nErrCode = RtlRosInitializeStack(ProcessHandle, &usUserInitialTeb);
6142 + struct pthread *pthread, *parent_pthread;
6143 + unsigned long pthread_size;
6145 + asm("movl %%gs:8, %0\n" : "=r"(parent_pthread));
6147 + pthread_size = (((unsigned long)parent_pthread + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) - (unsigned long)parent_pthread;
6148 + pthread = (struct pthread *)((unsigned long)usUserInitialTeb.StackBase - 0x800);
6149 + memcpy((void *)pthread, (void *)parent_pthread, pthread_size);
6151 + _dl_allocate_tls((void *)pthread);
6153 + pthread->header.tcb = pthread;
6154 + pthread->header.self = pthread;
6155 + pthread->header.multiple_threads = 1;
6156 + pthread->specific[0] = pthread->specific_1stblock;
6157 + pthread->user_stack = 1;
6158 + pthread->stackblock = (void *)((unsigned long)usUserInitialTeb.StackBase + PAGE_SIZE - DEFAULT_STACK_SIZE);
6159 + pthread->stackblock_size = DEFAULT_STACK_SIZE;
6160 + pthread->guardsize = pthread->reported_guardsize = DEFAULT_GUARD_SIZE / PAGE_SIZE;
6161 + pthread->list.next = &pthread->list;
6162 + pthread->list.prev = &pthread->list;
6164 + usUserInitialTeb.StackBase = (void *)((unsigned long)usUserInitialTeb.StackBase - PAGE_SIZE);
6167 + /* initialize the registers and stack for the thread */
6168 + nErrCode = RtlRosInitializeContext(ProcessHandle,
6169 + &ctxInitialContext,
6171 + &usUserInitialTeb,
6179 + if(BaseStartAddress) suspend = 1;
6180 + else suspend = CreateSuspended;
6182 + /* create the thread object */
6183 + nErrCode = NtCreateThread(ThreadHandle,
6184 + THREAD_ALL_ACCESS,
6188 + &ctxInitialContext,
6189 + &usUserInitialTeb,
6196 + if(BaseStartAddress) {
6197 + if (-1 == pipe(request_pipe))
6198 + return STATUS_TOO_MANY_OPENED_FILES;
6200 + /* set close on exec flag */
6201 + fcntl(request_pipe[1], F_SETFD, 1);
6202 + wine_server_send_fd(request_pipe[0]);
6204 + SERVER_START_REQ( new_thread )
6206 + req->access = THREAD_ALL_ACCESS;
6207 + req->attributes = 0; /* FIXME */
6208 + req->suspend = suspend;
6209 + req->request_fd = request_pipe[0];
6210 + req->tid = (int) ClientId->UniqueThread;
6211 + nErrCode = wine_server_call(req);
6213 + wine_handle = reply->handle;
6214 + close(request_pipe[0]);
6221 + if (!store_handle_pair(*ThreadHandle, wine_handle))
6224 + NtQueryInformationThread((*ThreadHandle), 0, &thread_info, sizeof(thread_info), NULL);
6225 + teb = thread_info.TebBaseAddress;
6226 + teb->ClientId.UniqueThread = teb->RealClientId.UniqueThread;
6227 + teb->ClientId.UniqueProcess = teb->RealClientId.UniqueProcess;
6229 + /* initialize some fields in teb and peb */
6230 + teb->StaticUnicodeString.Length = 0;
6231 + teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
6232 + teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
6234 + thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
6235 + thread_data->request_fd = request_pipe[1];
6236 + thread_data->reply_fd = -1;
6237 + thread_data->wait_fd[0] = -1;
6238 + thread_data->wait_fd[1] = -1;
6240 + if(!CreateSuspended) NtResumeThread((*ThreadHandle), NULL);
6243 + return STATUS_SUCCESS;
6249 + /* deallocate the stack */
6250 + RtlRosDeleteStack(ProcessHandle, &usUserInitialTeb);
6251 + close(request_pipe[1]);
6257 /***********************************************************************
6258 * RtlExitUserThread (NTDLL.@)
6259 @@ -618,6 +1471,7 @@
6263 +#ifndef UNIFIED_KERNEL
6264 SERVER_START_REQ( open_thread )
6266 req->tid = HandleToULong(id->UniqueThread);
6267 @@ -627,6 +1481,35 @@
6268 *handle = reply->handle;
6272 + PHANDLE uk_handle = handle;
6273 + HANDLE wine_handle;
6275 + __asm__ __volatile__ (
6276 + "movl $0x64,%%eax\n\t"
6277 + "lea 8(%%ebp),%%edx\n\t"
6284 + SERVER_START_REQ( open_thread)
6286 + req->tid = (thread_id_t)id->UniqueThread;
6287 + req->access = access;
6288 + req->attributes = attr ? attr->Attributes : 0;
6289 + ret = wine_server_call( req );
6292 + wine_handle = reply->handle;
6293 + if (!store_handle_pair(*uk_handle, wine_handle))
6294 + return STATUS_NO_MEMORY;
6303 @@ -639,12 +1522,36 @@
6307 +#ifndef UNIFIED_KERNEL
6308 SERVER_START_REQ( suspend_thread )
6310 req->handle = handle;
6311 if (!(ret = wine_server_call( req ))) *count = reply->count;
6315 + HANDLE wine_handle = GetCurrentThread();
6316 + struct handle_pair * pair;
6318 + __asm__ __volatile__ (
6319 + "movl $0xD0,%%eax\n\t"
6320 + "lea 8(%%ebp),%%edx\n\t"
6325 + pair = search_handle_pair(handle);
6327 + wine_handle = pair->wine_handle;
6329 + SERVER_START_REQ( suspend_thread )
6331 + req->handle = wine_handle;
6332 + wine_server_call( req );
6340 @@ -657,12 +1564,37 @@
6344 +#ifndef UNIFIED_KERNEL
6345 SERVER_START_REQ( resume_thread )
6347 req->handle = handle;
6348 if (!(ret = wine_server_call( req ))) *count = reply->count;
6352 + HANDLE wine_handle = GetCurrentThread();
6353 + struct handle_pair * pair;
6355 + pair = search_handle_pair(handle);
6357 + wine_handle = pair->wine_handle;
6359 + SERVER_START_REQ( resume_thread )
6361 + req->handle = wine_handle;
6362 + ret = wine_server_call( req );
6367 + __asm__ __volatile__ (
6368 + "movl $0xA8,%%eax\n\t"
6369 + "lea 8(%%ebp),%%edx\n\t"
6378 @@ -696,6 +1628,7 @@
6379 NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
6382 +#ifndef UNIFIED_KERNEL
6385 SERVER_START_REQ( terminate_thread )
6386 @@ -713,6 +1646,13 @@
6387 if (last) exit( exit_code );
6388 else server_abort_thread( exit_code );
6391 + __asm__ __volatile__ ( "movl $0xD4,%%eax\n\t"
6392 + "lea 8(%%ebp),%%edx\n\t"
6400 @@ -724,6 +1664,7 @@
6401 ULONG_PTR arg2, ULONG_PTR arg3 )
6404 +#ifndef UNIFIED_KERNEL
6405 SERVER_START_REQ( queue_apc )
6407 req->thread = handle;
6408 @@ -739,6 +1680,14 @@
6409 ret = wine_server_call( req );
6413 + __asm__ __volatile__ (
6414 + "movl $0x95,%%eax\n\t"
6415 + "lea 8(%%ebp),%%edx\n\t"
6423 @@ -767,9 +1716,19 @@
6427 +#ifdef UNIFIED_KERNEL
6428 + HANDLE wine_handle = NULL;
6429 + struct handle_pair * pair = search_handle_pair(handle);
6431 + wine_handle = pair->wine_handle;
6433 SERVER_START_REQ( set_thread_context )
6435 +#ifndef UNIFIED_KERNEL
6436 req->handle = handle;
6438 + req->handle = wine_handle;
6440 req->flags = context->ContextFlags;
6442 wine_server_add_data( req, context, sizeof(*context) );
6443 @@ -1066,9 +2025,19 @@
6447 +#ifdef UNIFIED_KERNEL
6448 + HANDLE wine_handle = NULL;
6449 + struct handle_pair * pair = search_handle_pair(handle);
6451 + handle = pair->wine_handle;
6453 SERVER_START_REQ( get_thread_context )
6455 +#ifndef UNIFIED_KERNEL
6456 req->handle = handle;
6458 + req->handle = wine_handle;
6460 req->flags = context->ContextFlags;
6462 wine_server_set_reply( req, &ctx, sizeof(ctx) );
6463 @@ -1143,6 +2112,7 @@
6467 +#ifndef UNIFIED_KERNEL
6470 case ThreadBasicInformation:
6471 @@ -1319,6 +2289,15 @@
6472 FIXME( "info class %d not supported yet\n", class );
6473 return STATUS_NOT_IMPLEMENTED;
6476 + __asm__ __volatile__ (
6477 + "movl $0x7E,%%eax\n\t"
6478 + "lea 8(%%ebp),%%edx\n\t"
6487 @@ -1330,6 +2309,7 @@
6488 LPCVOID data, ULONG length )
6491 +#ifndef UNIFIED_KERNEL
6494 case ThreadZeroTlsCell:
6495 @@ -1430,6 +2410,15 @@
6496 FIXME( "info class %d not supported yet\n", class );
6497 return STATUS_NOT_IMPLEMENTED;
6500 + __asm__ __volatile__ (
6501 + "movl $0xBB,%%eax\n\t"
6502 + "lea 8(%%ebp),%%edx\n\t"
6511 @@ -1450,7 +2439,16 @@
6513 TEB * WINAPI NtCurrentTeb(void)
6515 +#ifndef UNIFIED_KERNEL
6516 return pthread_functions.get_current_teb();
6519 + __asm__ __volatile__ (
6520 + "movl %%fs:0x18, %0\n"
6522 + : /* no inputs */ );
6527 #endif /* __i386__ */
6528 diff -urN wine-1.0/dlls/ntdll/threadpool.c wine-1.0-uk/dlls/ntdll/threadpool.c
6529 --- wine-1.0/dlls/ntdll/threadpool.c 2008-06-17 22:07:31.000000000 +0800
6530 +++ wine-1.0-uk/dlls/ntdll/threadpool.c 2009-08-19 10:13:55.000000000 +0800
6531 @@ -157,6 +157,22 @@
6535 +#ifdef UNIFIED_KERNEL
6536 +extern void (*ThreadStartup)(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);
6538 +RtlRosCreateUserThread(IN HANDLE ProcessHandle,
6539 + IN POBJECT_ATTRIBUTES ObjectAttributes,
6540 + IN BOOLEAN CreateSuspended,
6541 + IN LONG StackZeroBits,
6542 + IN OUT PULONG StackReserve OPTIONAL,
6543 + IN OUT PULONG StackCommit OPTIONAL,
6544 + IN PVOID BaseStartAddress,
6545 + OUT PHANDLE ThreadHandle OPTIONAL,
6546 + OUT PCLIENT_ID ClientId OPTIONAL,
6547 + IN ULONG_PTR StartAddress,
6548 + IN ULONG_PTR Parameter);
6551 /***********************************************************************
6552 * RtlQueueWorkItem (NTDLL.@)
6554 @@ -201,9 +217,15 @@
6555 if ((status == STATUS_SUCCESS) &&
6556 ((num_workers == 0) || (num_workers == num_busy_workers)))
6558 +#ifndef UNIFIED_KERNEL
6559 status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE,
6561 worker_thread_proc, NULL, &thread, NULL );
6563 + status = RtlRosCreateUserThread(GetCurrentProcess(),
6564 + NULL, FALSE, 0, NULL, NULL, (PVOID)ThreadStartup,
6565 + &thread, NULL, (ULONG_PTR)worker_thread_proc, 0);
6567 if (status == STATUS_SUCCESS)
6570 diff -urN wine-1.0/dlls/ntdll/virtual.c wine-1.0-uk/dlls/ntdll/virtual.c
6571 --- wine-1.0/dlls/ntdll/virtual.c 2008-06-17 22:07:31.000000000 +0800
6572 +++ wine-1.0-uk/dlls/ntdll/virtual.c 2009-08-19 11:02:45.000000000 +0800
6574 #define VFLAG_SYSTEM 0x01 /* system view (underlying mmap not under our control) */
6575 #define VFLAG_VALLOC 0x02 /* allocated by VirtualAlloc */
6577 +#ifdef UNIFIED_KERNEL
6578 +extern NTSTATUS WINAPI
6579 +NtWineService(struct __server_request_info * ReqMsg);
6582 /* Conversion from VPROT_* to Win32 flags */
6583 static const BYTE VIRTUAL_Win32Flags[16] =
6585 @@ -399,7 +404,14 @@
6587 static void delete_view( struct file_view *view ) /* [in] View */
6589 +#ifndef UNIFIED_KERNEL
6590 if (!(view->flags & VFLAG_SYSTEM)) unmap_area( view->base, view->size );
6592 + if (!(view->flags & VFLAG_SYSTEM)) {
6593 + unmap_area( view->base, view->size );
6594 + NtFreeVirtualMemory( NtCurrentProcess(), &view->base, &view->size, MEM_SYSTEM);
6597 list_remove( &view->entry );
6598 if (view->mapping) NtClose( view->mapping );
6604 +#ifndef UNIFIED_KERNEL
6605 /***********************************************************************
6606 * VIRTUAL_GetWin32Prot
6609 if (vprot & VPROT_GUARD) ret |= PAGE_GUARD;
6615 /***********************************************************************
6616 @@ -743,13 +757,22 @@
6618 TRACE( "got mem with anon mmap %p-%p\n", ptr, (char *)ptr + size );
6619 /* if we got something beyond the user limit, unmap it and retry */
6620 +#ifndef UNIFIED_KERNEL
6621 if (is_beyond_limit( ptr, view_size, user_space_limit )) add_reserved_area( ptr, view_size );
6624 + if (is_beyond_limit( ptr, view_size, (void *)0xc0000000 )) add_reserved_area( ptr, view_size );
6628 ptr = unmap_extra_space( ptr, view_size, size, mask );
6631 status = create_view( view_ret, ptr, size, vprot );
6632 +#ifdef UNIFIED_KERNEL
6633 + status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &size,
6634 + MEM_SYSTEM, PAGE_NOACCESS );
6636 if (status != STATUS_SUCCESS) unmap_area( ptr, size );
6643 +#ifndef UNIFIED_KERNEL
6644 /***********************************************************************
6649 return FILE_GetNtStatus();
6654 /***********************************************************************
6655 @@ -1373,6 +1398,7 @@
6656 NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_bits,
6657 SIZE_T *size_ptr, ULONG type, ULONG protect )
6659 +#ifndef UNIFIED_KERNEL
6662 SIZE_T size = *size_ptr;
6663 @@ -1489,6 +1515,16 @@
6670 + __asm__ __volatile__ (
6671 + "movl $0xB,%%eax\n\t"
6672 + "lea 8(%%ebp),%%edx\n\t"
6680 @@ -1499,6 +1535,7 @@
6682 NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *size_ptr, ULONG type )
6684 +#ifndef UNIFIED_KERNEL
6688 @@ -1583,6 +1620,16 @@
6691 server_leave_uninterrupted_section( &csVirtual, &sigset );
6695 + __asm__ __volatile__ (
6696 + "movl $0x40,%%eax\n\t"
6697 + "lea 8(%%ebp),%%edx\n\t"
6705 @@ -1594,6 +1641,7 @@
6706 NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *size_ptr,
6707 ULONG new_prot, ULONG *old_prot )
6709 +#ifndef UNIFIED_KERNEL
6712 NTSTATUS status = STATUS_SUCCESS;
6713 @@ -1668,6 +1716,16 @@
6720 + __asm__ __volatile__ (
6721 + "movl $0x6D,%%eax\n\t"
6722 + "lea 8(%%ebp),%%edx\n\t"
6730 @@ -1684,6 +1742,7 @@
6731 MEMORY_INFORMATION_CLASS info_class, PVOID buffer,
6732 SIZE_T len, SIZE_T *res_len )
6734 +#ifndef UNIFIED_KERNEL
6736 char *base, *alloc_base = 0;
6738 @@ -1806,6 +1865,17 @@
6739 info->RegionSize = size - (base - alloc_base);
6740 if (res_len) *res_len = sizeof(*info);
6741 return STATUS_SUCCESS;
6745 + __asm__ __volatile__ (
6746 + "movl $0x93,%%eax\n\t"
6747 + "lea 8(%%ebp),%%edx\n\t"
6756 @@ -1882,6 +1952,119 @@
6760 +#ifdef UNIFIED_KERNEL
6761 +NTSTATUS WINAPI UkCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
6762 + const LARGE_INTEGER *size, ULONG protect,
6763 + ULONG sec_flags, HANDLE file )
6766 + __asm__ __volatile__ (
6767 + "movl $0x24,%%eax\n\t"
6768 + "lea 8(%%ebp),%%edx\n\t"
6775 +NTSTATUS WINAPI UkOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
6778 + __asm__ __volatile__ (
6779 + "movl $0x61,%%eax\n\t"
6780 + "lea 8(%%ebp),%%edx\n\t"
6787 +NTSTATUS WINAPI UkMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_ptr, ULONG zero_bits,
6788 + SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
6789 + SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect )
6792 + __asm__ __volatile__ (
6793 + "movl $0x52,%%eax\n\t"
6794 + "lea 8(%%ebp),%%edx\n\t"
6801 +NTSTATUS WINAPI UkUnmapViewOfSection( HANDLE process, PVOID addr )
6804 + __asm__ __volatile__ (
6805 + "movl $0xdc,%%eax\n\t"
6806 + "lea 8(%%ebp),%%edx\n\t"
6813 +NTSTATUS WINAPI UkQuerySection(
6814 + IN HANDLE SectionHandle,
6815 + IN SECTION_INFORMATION_CLASS SectionInformationClass,
6816 + OUT PVOID SectionInformation,
6818 + OUT PULONG ResultLength)
6821 + __asm__ __volatile__(
6822 + "movl $0x89,%%eax\n\t"
6823 + "lea 8(%%ebp),%%edx\n\t"
6830 +NTSTATUS WINAPI UkAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_bits,
6831 + SIZE_T *size_ptr, ULONG type, ULONG protect )
6835 + __asm__ __volatile__ (
6836 + "movl $0xB,%%eax\n\t"
6837 + "lea 8(%%ebp),%%edx\n\t"
6844 +NTSTATUS WINAPI UkWriteVirtualMemory( HANDLE process, void *addr, const void *buffer,
6845 + SIZE_T size, SIZE_T *bytes_written )
6849 + __asm__ __volatile__ (
6850 + "movl $0xE5,%%eax\n\t"
6851 + "lea 8(%%ebp),%%edx\n\t"
6858 +NTSTATUS WINAPI UkReadVirtualMemory( HANDLE process, const void *addr, void *buffer,
6859 + SIZE_T size, SIZE_T *bytes_read )
6863 + __asm__ __volatile__ (
6864 + "movl $0x9B,%%eax\n\t"
6865 + "lea 8(%%ebp),%%edx\n\t"
6874 /***********************************************************************
6875 * NtCreateSection (NTDLL.@)
6876 @@ -1891,6 +2074,7 @@
6877 const LARGE_INTEGER *size, ULONG protect,
6878 ULONG sec_flags, HANDLE file )
6880 +#ifndef UNIFIED_SECTION
6883 DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0;
6884 @@ -1931,7 +2115,11 @@
6885 wine_server_add_data( req, &objattr, sizeof(objattr) );
6886 if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
6887 if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
6888 +#ifndef UNIFIED_KERNEL
6889 ret = wine_server_call( req );
6891 + ret = NtWineService( req );
6893 *handle = reply->handle;
6896 @@ -1939,6 +2127,16 @@
6897 NTDLL_free_struct_sd( sd );
6902 + __asm__ __volatile__ (
6903 + "movl $0x24,%%eax\n\t"
6904 + "lea 8(%%ebp),%%edx\n\t"
6913 @@ -1948,6 +2146,7 @@
6915 NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
6917 +#ifndef UNIFIED_SECTION
6919 DWORD len = attr->ObjectName->Length;
6921 @@ -1959,10 +2158,24 @@
6922 req->attributes = attr->Attributes;
6923 req->rootdir = attr->RootDirectory;
6924 wine_server_add_data( req, attr->ObjectName->Buffer, len );
6925 +#ifndef UNIFIED_KERNEL
6926 if (!(ret = wine_server_call( req ))) *handle = reply->handle;
6928 + if (!(ret = NtWineService( req ))) *handle = reply->handle;
6935 + __asm__ __volatile__ (
6936 + "movl $0x61,%%eax\n\t"
6937 + "lea 8(%%ebp),%%edx\n\t"
6946 @@ -1974,6 +2187,7 @@
6947 SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
6948 SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect )
6950 +#ifndef UNIFIED_SECTION
6952 ULONGLONG full_size;
6954 @@ -2026,7 +2240,11 @@
6955 SERVER_START_REQ( get_mapping_info )
6957 req->handle = handle;
6958 +#ifndef UNIFIED_KERNEL
6959 res = wine_server_call( req );
6961 + res = NtWineService( req );
6963 prot = reply->protect;
6965 full_size = reply->size;
6966 @@ -2054,7 +2272,9 @@
6967 &shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
6968 res = map_image( handle, unix_handle, base, size, mask, header_size,
6969 shared_fd, dup_mapping, addr_ptr );
6970 +#ifndef UNIFIED_KERNEL
6971 if (shared_needs_close) close( shared_fd );
6973 NtClose( shared_file );
6976 @@ -2062,7 +2282,9 @@
6977 res = map_image( handle, unix_handle, base, size, mask, header_size,
6978 -1, dup_mapping, addr_ptr );
6980 +#ifndef UNIFIED_KERNEL
6981 if (needs_close) close( unix_handle );
6983 if (!res) *size_ptr = size;
6986 @@ -2142,8 +2364,19 @@
6989 if (dup_mapping) NtClose( dup_mapping );
6990 +#ifndef UNIFIED_KERNEL
6991 if (needs_close) close( unix_handle );
6996 + __asm__ __volatile__ (
6997 + "movl $0x52,%%eax\n\t"
6998 + "lea 8(%%ebp),%%edx\n\t"
7006 @@ -2153,6 +2386,7 @@
7008 NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
7010 +#ifndef UNIFIED_SECTION
7012 NTSTATUS status = STATUS_INVALID_PARAMETER;
7014 @@ -2180,6 +2414,16 @@
7016 server_leave_uninterrupted_section( &csVirtual, &sigset );
7020 + __asm__ __volatile__ (
7021 + "movl $0xdc,%%eax\n\t"
7022 + "lea 8(%%ebp),%%edx\n\t"
7031 @@ -2190,6 +2434,7 @@
7032 NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
7033 SIZE_T *size_ptr, ULONG unknown )
7035 +#ifndef UNIFIED_KERNEL
7037 NTSTATUS status = STATUS_SUCCESS;
7039 @@ -2225,6 +2470,16 @@
7040 if (msync( addr, *size_ptr, MS_SYNC )) status = STATUS_NOT_MAPPED_DATA;
7042 server_leave_uninterrupted_section( &csVirtual, &sigset );
7046 + __asm__ __volatile__ (
7047 + "movl $0x3E,%%eax\n\t"
7048 + "lea 8(%%ebp),%%edx\n\t"
7056 @@ -2238,6 +2493,7 @@
7060 +#ifndef UNIFIED_KERNEL
7061 SERVER_START_REQ( read_process_memory )
7063 req->handle = process;
7064 @@ -2247,6 +2503,14 @@
7067 if (bytes_read) *bytes_read = size;
7069 + __asm__ __volatile__ (
7070 + "movl $0x9B,%%eax\n\t"
7071 + "lea 8(%%ebp),%%edx\n\t"
7079 @@ -2260,6 +2524,7 @@
7083 +#ifndef UNIFIED_KERNEL
7084 SERVER_START_REQ( write_process_memory )
7086 req->handle = process;
7087 @@ -2269,6 +2534,14 @@
7090 if (bytes_written) *bytes_written = size;
7092 + __asm__ __volatile__ (
7093 + "movl $0xE5,%%eax\n\t"
7094 + "lea 8(%%ebp),%%edx\n\t"
7102 @@ -2283,3 +2556,42 @@
7104 return STATUS_NOT_SAME_DEVICE;
7107 +#ifdef UNIFIED_KERNEL
7108 +#define ALIGN_UP(addr, align) (((addr) + (align) - 1) & ~((align) - 1))
7110 + * create_pe_sec_view
7112 + * create view for pe sections
7114 +NTSTATUS create_pe_sec_view(HANDLE hmodule)
7116 + IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hmodule);
7117 + IMAGE_SECTION_HEADER *sec;
7118 + NTSTATUS status = 0;
7119 + struct file_view *view;
7121 + void *virtual_addr;
7122 + size_t virtual_size, size = 0;
7124 + sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
7125 + sec_align = nt->OptionalHeader.SectionAlignment;
7129 + size = ALIGN_UP(sec->VirtualAddress, sec_align);
7130 + for (i=0; i<nt->FileHeader.NumberOfSections; i++, sec++) {
7131 + virtual_size = ALIGN_UP(sec->Misc.VirtualSize, sec_align);
7132 + size += virtual_size;
7135 + virtual_addr = (void *)ALIGN_UP((ULONG)hmodule, sec_align);
7136 + status = create_view(&view, virtual_addr, size,
7137 + VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC | VPROT_COMMITTED);
7138 + if (status != STATUS_SUCCESS)
7141 + view->flags |= VFLAG_VALLOC;
7145 diff -urN wine-1.0/dlls/user32/defwnd.c wine-1.0-uk/dlls/user32/defwnd.c
7146 --- wine-1.0/dlls/user32/defwnd.c 2008-06-17 22:07:31.000000000 +0800
7147 +++ wine-1.0-uk/dlls/user32/defwnd.c 2009-08-18 16:11:13.000000000 +0800
7151 RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
7152 +#ifndef UNIFIED_KERNEL /* FIXME */
7153 WIN_SetStyle( hwnd, 0, WS_VISIBLE );
7158 diff -urN wine-1.0/dlls/user32/dialog.c wine-1.0-uk/dlls/user32/dialog.c
7159 --- wine-1.0/dlls/user32/dialog.c 2008-06-17 22:07:31.000000000 +0800
7160 +++ wine-1.0-uk/dlls/user32/dialog.c 2009-08-18 16:11:13.000000000 +0800
7161 @@ -588,7 +588,11 @@
7164 ownerEnabled = DIALOG_DisableOwner( owner );
7165 +#ifndef UNIFIED_KERNEL
7166 if (ownerEnabled) flags |= DF_OWNERENABLED;
7168 + if (ownerEnabled || owner == GetActiveWindow()) flags |= DF_OWNERENABLED;
7173 diff -urN wine-1.0/dlls/user32/edit.c wine-1.0-uk/dlls/user32/edit.c
7174 --- wine-1.0/dlls/user32/edit.c 2008-06-17 22:07:31.000000000 +0800
7175 +++ wine-1.0-uk/dlls/user32/edit.c 2009-08-18 16:11:13.000000000 +0800
7176 @@ -2595,16 +2595,38 @@
7177 while (index && (s[index] == ' '))
7180 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7181 while (index && (s[index] != ' '))
7183 if (s[index] == ' ')
7186 + if (!(s[index] & 0xFF00)) {
7187 + while (index && (s[index] != ' ') && !(s[index] & 0xFF00))
7189 + if (s[index] & 0xFF00)
7192 + if (s[index] == ' ')
7197 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7198 while (index && (s[index] != ' '))
7200 if (s[index] == ' ')
7203 + if (!(s[index] & 0xFF00)) {
7204 + while (index && (s[index] != ' ') && !(s[index] & 0xFF00))
7206 + if (s[index] & 0xFF00)
7209 + if (s[index] == ' ')
7215 @@ -2616,8 +2638,17 @@
7216 if (s[index] == ' ')
7217 while ((index < count) && (s[index] == ' ')) index++;
7219 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7220 while (s[index] && (s[index] != ' ') && (index < count))
7223 + if (!(s[index] & 0xFF00))
7224 + while (s[index] && (s[index] != ' ')
7225 + && (index < count) && !(s[index] & 0xFF00))
7230 while ((s[index] == ' ') && (index < count)) index++;
7233 diff -urN wine-1.0/dlls/user32/mdi.c wine-1.0-uk/dlls/user32/mdi.c
7234 --- wine-1.0/dlls/user32/mdi.c 2008-06-17 22:07:31.000000000 +0800
7235 +++ wine-1.0-uk/dlls/user32/mdi.c 2009-08-18 16:11:13.000000000 +0800
7236 @@ -1884,8 +1884,85 @@
7237 CascadeWindows (HWND hwndParent, UINT wFlags, const RECT *lpRect,
7238 UINT cKids, const HWND *lpKids)
7240 +#ifndef UNIFIED_KERNEL
7241 FIXME("(%p,0x%08x,...,%u,...): stub\n", hwndParent, wFlags, cKids);
7244 + MDICLIENTINFO *ci;
7246 + BOOL has_icons = FALSE;
7249 + if(!(ci = get_client_info( hwndParent ))) return 0;
7251 + if (ci->hwndChildMaximized)
7252 + SendMessageW(hwndParent, WM_MDIRESTORE, (WPARAM)ci->hwndChildMaximized, 0);
7254 + if (!(win_array = WIN_ListChildren( hwndParent )))
7256 + HeapFree( GetProcessHeap(), 0, ci );
7260 + /* remove all the windows we don't want */
7261 + for (i = total = 0; win_array[i]; i++)
7263 + if (!IsWindowVisible( win_array[i] )) continue;
7264 + if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows */
7265 + if (IsIconic( win_array[i] ))
7273 + HeapFree( GetProcessHeap(), 0, win_array );
7277 + if (ci->nActiveChildren == 0)
7279 + HeapFree( GetProcessHeap(), 0, ci );
7286 + INT delta = 0, n = 0, i;
7290 + delta = GetSystemMetrics(SM_CYICONSPACING) + GetSystemMetrics(SM_CYICON);
7292 + tmpid = (HWND *)lpKids;
7293 + /* walk the list (backwards) and move windows */
7294 + for (i = cKids - 1; i >= 0; i--)
7296 + TRACE("move %p to (%d,%d) size [%d,%d]\n",
7297 + tmpid[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
7299 + MDI_CalcDefaultChildPos(hwndParent, n++, pos, delta, NULL);
7300 + SetWindowPos( tmpid[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
7301 + SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
7305 + if (has_icons) ArrangeIconicWindows( hwndParent);
7307 + HeapFree( GetProcessHeap(), 0, ci );
7312 + /* cascade child windows */
7313 + MDICascade(hwndParent, ci);
7315 + HeapFree( GetProcessHeap(), 0, ci );
7322 @@ -1909,8 +1986,98 @@
7323 TileWindows (HWND hwndParent, UINT wFlags, const RECT *lpRect,
7324 UINT cKids, const HWND *lpKids)
7326 +#ifndef UNIFIED_KERNEL
7327 FIXME("(%p,0x%08x,...,%u,...): stub\n", hwndParent, wFlags, cKids);
7330 + /* Arrange child windows horizontally or vertically
7331 + Compare child windows abreast */
7332 + MDICLIENTINFO *ci;
7334 + BOOL has_icons = FALSE;
7337 + if (!(ci = get_client_info(hwndParent)))
7340 + for (hwndChild = GetTopWindow(hwndParent), total = 0; hwndChild != NULL;
7341 + hwndChild = GetNextWindow(hwndChild, GW_HWNDNEXT)) {
7342 + if (!IsWindowVisible(hwndChild))
7344 + if (GetWindow(hwndChild, GW_OWNER))
7346 + if (IsIconic(hwndChild)) {
7350 + if ((wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwndChild))
7357 + MDITile(hwndParent, ci, wFlags);
7359 + HeapFree(GetProcessHeap(), 0, ci);
7363 + /* Refered to MDITile() */
7364 + HWND *pWnd = (HWND *)lpKids;
7366 + int x, y, xsize, ysize;
7367 + int rows, columns, r, c, i;
7370 + HeapFree(GetProcessHeap(), 0, ci);
7374 + if (ci->hwndChildMaximized)
7375 + SendMessageW(hwndParent, WM_MDIRESTORE, (WPARAM)ci->hwndChildMaximized, 0);
7377 + GetClientRect(hwndParent, &rect);
7378 + rows = (int)sqrt((double)cKids);
7379 + columns = cKids / rows;
7381 + if (wFlags & MDITILE_HORIZONTAL) {
7388 + y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING)
7389 + - GetSystemMetrics(SM_CYICON);
7390 + rect.bottom = (y - GetSystemMetrics(SM_CYICON) < rect.top) ? rect.bottom : y;
7393 + ysize = rect.bottom / rows;
7394 + xsize = rect.right / columns;
7396 + for (x = i = 0, c = 1; c <= columns && *pWnd; c++) {
7397 + if (c == columns) {
7399 + ysize = rect.bottom / rows;
7403 + for (r = 1; r <= rows && *pWnd; r++, i++) {
7404 + SetWindowPos(*pWnd, 0, x, y, xsize, ysize,
7405 + SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
7411 + HeapFree(GetProcessHeap(), 0, ci);
7414 + ArrangeIconicWindows(hwndParent);
7421 diff -urN wine-1.0/dlls/user32/message.c wine-1.0-uk/dlls/user32/message.c
7422 --- wine-1.0/dlls/user32/message.c 2008-06-17 22:07:31.000000000 +0800
7423 +++ wine-1.0-uk/dlls/user32/message.c 2009-08-18 16:11:13.000000000 +0800
7426 #include "controls.h"
7427 #include "wine/debug.h"
7428 +#ifdef UNIFIED_KERNEL
7429 +#include "handle.h"
7432 WINE_DEFAULT_DEBUG_CHANNEL(msg);
7433 WINE_DECLARE_DEBUG_CHANNEL(relay);
7434 @@ -3254,6 +3257,11 @@
7435 DWORD start_time, elapsed, ret;
7438 +#ifdef UNIFIED_KERNEL
7439 + struct handle_pair* pair = search_handle_pair(hProcess);
7441 + hProcess = pair->wine_handle;
7443 handles[0] = hProcess;
7444 SERVER_START_REQ( get_process_idle_event )
7446 diff -urN wine-1.0/dlls/user32/text.c wine-1.0-uk/dlls/user32/text.c
7447 --- wine-1.0/dlls/user32/text.c 2008-06-17 22:07:31.000000000 +0800
7448 +++ wine-1.0-uk/dlls/user32/text.c 2009-08-18 16:11:13.000000000 +0800
7449 @@ -367,10 +367,38 @@
7450 ; /* we pretend that it fits anyway */
7451 else if (*p == SPACE) /* chars_fit < *len_str so this is valid */
7452 p--; /* the word just fitted */
7453 +#ifdef UNIFIED_KERNEL
7454 + else if (*p >= 0x2e81 && *p <= 0xffe5)
7456 + /* Chinese punctuation character: , . ? ! ) >> ' ' " ; : */
7458 + *p == 0x2018 /* ) */
7459 + || *p == 0x2019 /* ! */
7460 + || *p == 0x201D /* ? */
7461 + || *p == 0x3002 /* ; */
7462 + || *p == 0x300B /* >> */
7463 + || *p == 0xFF01 /* '(right) */
7464 + || *p == 0xFF09 /* '(left) */
7465 + || *p == 0xFF0C /* : */
7466 + || *p == 0xFF1A /* , */
7467 + || *p == 0xFF1B /* . */
7468 + || *p == 0xFF1F /* "(right) */
7471 + /* CJK characters are treated breakable */
7477 +#ifndef UNIFIED_KERNEL
7478 while (p > str && *(--p) != SPACE)
7481 + /* if Chinese and English mix up */
7482 + while (p > str && *p != SPACE && (*p < 0x3012 || *p > 0xFA29 ) )
7485 word_fits = (p != str || *p == SPACE);
7487 /* If there was one or the first character didn't fit then */
7488 diff -urN wine-1.0/dlls/user32/winpos.c wine-1.0-uk/dlls/user32/winpos.c
7489 --- wine-1.0/dlls/user32/winpos.c 2008-06-17 22:07:31.000000000 +0800
7490 +++ wine-1.0-uk/dlls/user32/winpos.c 2009-08-18 16:11:13.000000000 +0800
7491 @@ -859,6 +859,10 @@
7494 WINDOWPLACEMENT wpl;
7495 +#ifdef UNIFIED_KERNEL
7500 TRACE("%p %u\n", hwnd, cmd );
7502 @@ -913,7 +917,16 @@
7503 if (old_style & WS_MINIMIZE) WINPOS_ShowIconTitle( hwnd, FALSE );
7505 if (!(old_style & WS_MAXIMIZE)) swpFlags |= SWP_STATECHANGED;
7506 +#ifdef UNIFIED_KERNEL
7507 + parent = GetWindowRect((HWND)GetWindowLongW(hwnd, GWLP_HWNDPARENT), &parent_rect);
7509 + SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
7510 + parent_rect.right - parent_rect.left, parent_rect.bottom - parent_rect.top);
7512 + SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
7514 SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
7518 case SW_SHOWNOACTIVATE:
7519 diff -urN wine-1.0/dlls/winex11.drv/event.c wine-1.0-uk/dlls/winex11.drv/event.c
7520 --- wine-1.0/dlls/winex11.drv/event.c 2008-06-17 22:07:31.000000000 +0800
7521 +++ wine-1.0-uk/dlls/winex11.drv/event.c 2009-08-18 16:11:13.000000000 +0800
7522 @@ -334,7 +334,14 @@
7523 while (XCheckIfEvent( display, &event, filter, (char *)arg ))
7526 +#ifndef UNIFIED_KERNEL
7527 if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */
7529 + if(event.type != KeyRelease) /* do not filter key release event */
7531 + if (XFilterEvent( &event, None )==True) continue; /* filtered, ignore it */
7534 if (prev_event.type) action = merge_events( &prev_event, &event );
7537 diff -urN wine-1.0/dlls/winex11.drv/text.c wine-1.0-uk/dlls/winex11.drv/text.c
7538 --- wine-1.0/dlls/winex11.drv/text.c 2008-06-17 22:07:31.000000000 +0800
7539 +++ wine-1.0-uk/dlls/winex11.drv/text.c 2009-08-18 16:11:13.000000000 +0800
7542 HRGN saved_region = 0;
7544 +#ifndef UNIFIED_KERNEL
7545 if(physDev->has_gdi_font)
7546 return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx);
7548 + if(physDev->has_gdi_font)
7554 + hdc = physDev->hdc;
7555 + GetTextMetricsW(hdc, &tmw);
7557 + if (!(flags & ETO_ROTATE))
7559 + if(flags & ETO_BOLD_FLAG1)
7561 + X11DRV_XRender_ExtTextOut(physDev, x + 1, y, flags, lprect,
7562 + wstr, count, lpDx);
7564 + /* if font is bold ,the draw text twice or more! */
7565 + if(flags & ETO_BOLD_FLAG2)
7568 + font_heigh = (int)(tmw.tmHeight / 210);
7569 + /* judge font heignt */
7570 + if(tmw.tmHeight <= 210)
7572 + X11DRV_XRender_ExtTextOut(physDev, x + 1, y, flags, lprect,
7573 + wstr, count, lpDx);
7575 + else if(tmw.tmHeight <= 410 )
7579 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 1),
7580 + y + (int)(font_heigh * 0.3),
7581 + flags, lprect, wstr, count, lpDx);
7587 + else if(tmw.tmHeight <= 720)
7591 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.7),
7592 + y + (int)(font_heigh * 0.3),
7593 + flags, lprect, wstr, count, lpDx);
7600 + font_heigh = (font_heigh*0.5);
7603 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.5),
7604 + y + (int)(font_heigh * 0.25),
7605 + flags, lprect, wstr, count, lpDx);
7606 + X11DRV_XRender_ExtTextOut(physDev, x - (int)(font_heigh * 0.5),
7607 + y - (int)(font_heigh * 0.25),
7608 + flags, lprect, wstr, count, lpDx);
7610 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.5), y,
7611 + flags, lprect, wstr, count, lpDx);
7612 + X11DRV_XRender_ExtTextOut(physDev, x - (int)(font_heigh * 0.5), y,
7613 + flags, lprect, wstr, count, lpDx);
7614 + X11DRV_XRender_ExtTextOut(physDev, x, y + (int)(font_heigh * 0.25),
7615 + flags, lprect, wstr, count, lpDx);
7616 + X11DRV_XRender_ExtTextOut(physDev, x, y - (int)(font_heigh * 0.25),
7617 + flags, lprect, wstr, count, lpDx);
7622 + } /* end bold_flag2 */
7623 + } /* if !rotate */
7626 + if(flags & ETO_BOLD_FLAG1)
7628 + X11DRV_XRender_ExtTextOut(physDev, x, y + 1, flags, lprect,
7629 + wstr, count, lpDx);
7631 + /* if font is bold ,the draw text twice or more! */
7632 + if(flags & ETO_BOLD_FLAG2)
7635 + font_heigh = (int)(tmw.tmHeight / 210);
7636 + /* judge font heignt */
7637 + if(tmw.tmHeight <= 210)
7639 + X11DRV_XRender_ExtTextOut(physDev, x, y + 1, flags, lprect, wstr, count, lpDx);
7641 + else if(tmw.tmHeight <= 410 )
7645 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.3),
7646 + y + (int)(font_heigh * 1),
7647 + flags, lprect, wstr, count, lpDx);
7653 + else if(tmw.tmHeight <= 720)
7657 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.3),
7658 + y + (int)(font_heigh * 0.7),
7659 + flags, lprect, wstr, count, lpDx);
7666 + font_heigh = (font_heigh*0.5);
7669 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.25),
7670 + y + (int)(font_heigh * 0.5),
7671 + flags, lprect, wstr, count, lpDx);
7672 + X11DRV_XRender_ExtTextOut(physDev, x - (int)(font_heigh * 0.25),
7673 + y - (int)(font_heigh * 0.5),
7674 + flags, lprect, wstr, count, lpDx);
7676 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.25), y,
7677 + flags, lprect, wstr, count, lpDx);
7678 + X11DRV_XRender_ExtTextOut(physDev, x - (int)(font_heigh * 0.25), y,
7679 + flags, lprect, wstr, count, lpDx);
7680 + X11DRV_XRender_ExtTextOut(physDev, x, y + (int)(font_heigh * 0.5),
7681 + flags, lprect, wstr, count, lpDx);
7682 + X11DRV_XRender_ExtTextOut(physDev, x, y - (int)(font_heigh * 0.5),
7683 + flags, lprect, wstr, count, lpDx);
7690 + return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx);
7694 if (!X11DRV_SetupGCForText( physDev )) return TRUE;
7696 diff -urN wine-1.0/dlls/winex11.drv/xdnd.c wine-1.0-uk/dlls/winex11.drv/xdnd.c
7697 --- wine-1.0/dlls/winex11.drv/xdnd.c 2008-06-17 22:07:31.000000000 +0800
7698 +++ wine-1.0-uk/dlls/winex11.drv/xdnd.c 2009-08-18 16:11:13.000000000 +0800
7699 @@ -393,7 +393,11 @@
7703 +#ifndef UNIFIED_KERNEL /* modify for dragging file with Chinese file name */
7704 int pathSize = strlenW(path) + 1;
7706 + int pathSize = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, 0, 0);
7708 if (pathSize > capacity-size)
7710 capacity = 2*capacity + pathSize;
7711 diff -urN wine-1.0/include/handle.h wine-1.0-uk/include/handle.h
7712 --- wine-1.0/include/handle.h 1970-01-01 08:00:00.000000000 +0800
7713 +++ wine-1.0-uk/include/handle.h 2009-08-19 12:44:28.000000000 +0800
7718 + * Copyright (C) 2006 Insigme Co., Ltd
7720 + * This software has been developed while working on the Linux Unified Kernel
7721 + * project (http://linux.insigma.com.cn) in the Insigma Research Institute,
7722 + * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn).
7724 + * The project is sponsored by Insigma Co., Ltd.
7726 + * The authors can be reached at linux@insigma.com.cn.
7728 + * This program is free software; you can redistribute it and/or modify it
7729 + * under the terms of the GNU General Public License as published by the
7730 + * Free Software Foundation; either version 2 of the License, or (at your
7731 + * option) any later version.
7733 + * Revision History:
7734 + * Jan 2006 - Created.
7738 + * handle.h: We use Unified Kernel handles to make it compatible with Wine's
7742 +#ifndef __UK_HANDLE_H
7743 +#define __UK_HANDLE_H
7745 +#ifdef UNIFIED_KERNEL
7746 +#include "wine/list.h"
7749 + * if the handle value greater than (1<<15), it will fault when someone
7752 +#define UK_HANDLE_FLAG (1 << 15)
7753 +#define HANDLE_TO_UK_HANDLE(handle) \
7754 + (HANDLE)((ULONG_PTR)(handle) | UK_HANDLE_FLAG)
7755 +#define UK_HANDLE_TO_HANDLE(handle) \
7756 + (HANDLE)((ULONG_PTR)(handle) & ~UK_HANDLE_FLAG)
7758 +#define IS_UK_HANDLE(handle) \
7759 + ((ULONG_PTR)(handle) & UK_HANDLE_FLAG)
7763 + struct list entry;
7765 + HANDLE wine_handle;
7768 +struct handle_pair* search_handle_pair(HANDLE uk_handle);
7769 +void delete_handle_pair(struct handle_pair* pair);
7770 +int store_handle_pair(HANDLE uk_handle, HANDLE wine_handle);
7771 +#endif /* UNIFIED_KERNEL */
7773 +#endif /* __UK_HANDLE_H */
7774 diff -urN wine-1.0/include/winbase.h wine-1.0-uk/include/winbase.h
7775 --- wine-1.0/include/winbase.h 2008-06-17 22:07:31.000000000 +0800
7776 +++ wine-1.0-uk/include/winbase.h 2009-08-18 16:11:13.000000000 +0800
7777 @@ -1444,7 +1444,11 @@
7778 WINADVAPI BOOL WINAPI EqualPrefixSid(PSID,PSID);
7779 WINBASEAPI DWORD WINAPI EraseTape(HANDLE,DWORD,BOOL);
7780 WINBASEAPI VOID DECLSPEC_NORETURN WINAPI ExitProcess(DWORD);
7781 +#ifndef UNIFIED_KERNEL
7782 WINBASEAPI VOID DECLSPEC_NORETURN WINAPI ExitThread(DWORD);
7784 +VOID WINAPI ExitThread(DWORD);
7786 WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD);
7787 WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD);
7788 #define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
7789 diff -urN wine-1.0/include/wine/server_protocol.h wine-1.0-uk/include/wine/server_protocol.h
7790 --- wine-1.0/include/wine/server_protocol.h 2008-06-17 22:07:31.000000000 +0800
7791 +++ wine-1.0-uk/include/wine/server_protocol.h 2009-08-18 16:11:13.000000000 +0800
7793 unsigned int attributes;
7796 +#ifdef UNIFIED_KERNEL
7800 struct new_thread_reply
7802 @@ -541,6 +544,10 @@
7806 +#ifdef UNIFIED_KERNEL
7811 struct init_thread_reply
7813 @@ -1070,6 +1077,7 @@
7815 unsigned int access;
7816 unsigned int options;
7821 diff -urN wine-1.0/include/wingdi.h wine-1.0-uk/include/wingdi.h
7822 --- wine-1.0/include/wingdi.h 2008-06-17 22:07:31.000000000 +0800
7823 +++ wine-1.0-uk/include/wingdi.h 2009-08-18 16:11:13.000000000 +0800
7824 @@ -1269,6 +1269,11 @@
7825 #define ETO_NUMERICSLATIN 0x0800
7826 #define ETO_IGNORELANGUAGE 0x1000
7827 #define ETO_PDY 0x2000
7828 +#ifdef UNIFIED_KERNEL
7829 +#define ETO_BOLD_FLAG1 0x4000
7830 +#define ETO_BOLD_FLAG2 0x8000
7831 +#define ETO_ROTATE 0x0008
7834 #define ASPECT_FILTERING 0x0001
7836 @@ -3398,7 +3403,12 @@
7837 WINGDIAPI BOOL WINAPI ExtFloodFill(HDC,INT,INT,COLORREF,UINT);
7838 WINGDIAPI INT WINAPI ExtSelectClipRgn(HDC,HRGN,INT);
7839 WINGDIAPI BOOL WINAPI ExtTextOutA(HDC,INT,INT,UINT,const RECT*,LPCSTR,UINT,const INT*);
7840 +#ifndef UNIFIED_KERNEL
7841 WINGDIAPI BOOL WINAPI ExtTextOutW(HDC,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
7843 +BOOL WINAPI ExtTextOutW(HDC,INT,INT,UINT,const RECT*,
7844 + LPWSTR,UINT,const INT*);
7846 #define ExtTextOut WINELIB_NAME_AW(ExtTextOut)
7847 WINGDIAPI BOOL WINAPI FillPath(HDC);
7848 WINGDIAPI BOOL WINAPI FillRgn(HDC,HRGN,HBRUSH);
7849 diff -urN wine-1.0/include/winternl.h wine-1.0-uk/include/winternl.h
7850 --- wine-1.0/include/winternl.h 2008-06-17 22:07:31.000000000 +0800
7851 +++ wine-1.0-uk/include/winternl.h 2009-08-18 16:11:13.000000000 +0800
7852 @@ -2158,7 +2158,11 @@
7853 NTSYSAPI BOOL WINAPI RtlEqualSid(PSID,PSID);
7854 NTSYSAPI BOOLEAN WINAPI RtlEqualString(const STRING*,const STRING*,BOOLEAN);
7855 NTSYSAPI BOOLEAN WINAPI RtlEqualUnicodeString(const UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
7856 +#ifndef UNIFIED_KERNEL
7857 NTSYSAPI void DECLSPEC_NORETURN WINAPI RtlExitUserThread(ULONG);
7859 +void WINAPI RtlExitUserThread(ULONG);
7861 NTSYSAPI NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR, const UNICODE_STRING*, UNICODE_STRING*, ULONG*);
7862 NTSYSAPI LONGLONG WINAPI RtlExtendedMagicDivide(LONGLONG,LONGLONG,INT);
7863 NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG,INT);
7864 diff -urN wine-1.0/libs/wine/config.c wine-1.0-uk/libs/wine/config.c
7865 --- wine-1.0/libs/wine/config.c 2008-06-17 22:07:31.000000000 +0800
7866 +++ wine-1.0-uk/libs/wine/config.c 2009-08-18 16:11:13.000000000 +0800
7871 +#ifndef UNIFIED_KERNEL_EXESO
7872 static const char preloader[] = "wine-preloader";
7873 char *p, *full_name;
7874 char **last_arg = argv, **new_argv;
7875 @@ -444,6 +445,40 @@
7881 + char **last_arg = argv, **new_argv;
7883 + /* make a copy of argv */
7884 + while (*last_arg) last_arg++;
7885 + new_argv = xmalloc( (last_arg - argv) * sizeof(*argv) );
7888 + memcpy( new_argv, argv + 1, (last_arg - argv) * sizeof(*argv) );
7890 + get_dlldir((const char **)&p);
7891 + if(strchr(new_argv[0], '/') == NULL) {
7892 + new_argv[0] = xmalloc(strlen(p) + strlen(argv[1]) + 1 + 1 + 7);
7893 + if(new_argv[0] == NULL) {
7897 + strcpy(new_argv[0], p);
7898 + strcat(new_argv[0], "/");
7899 + strcat(new_argv[0], argv[1]);
7900 + if((p = strrchr(argv[1], '.')) == NULL)
7901 + strcat(new_argv[0], ".exe.so");
7903 + if(strcmp(p, ".exe") == 0) {
7904 + strcat(new_argv[0], ".so");
7909 + execv( new_argv[0], new_argv );
7915 execv( argv[0], argv );
7916 diff -urN wine-1.0/libs/wine/debug.c wine-1.0-uk/libs/wine/debug.c
7917 --- wine-1.0/libs/wine/debug.c 2008-06-17 22:07:31.000000000 +0800
7918 +++ wine-1.0-uk/libs/wine/debug.c 2009-08-18 16:11:13.000000000 +0800
7919 @@ -119,7 +119,11 @@
7922 /* parse a set of debugging option specifications and add them to the option list */
7923 +#ifndef UNIFIED_KERNEL
7924 static void parse_options( const char *str )
7926 +void parse_options( const char *str )
7929 char *opt, *next, *options;
7931 @@ -169,7 +173,11 @@
7934 /* print the usage message */
7935 +#ifndef UNIFIED_KERNEL
7936 static void debug_usage(void)
7938 +void debug_usage(void)
7941 static const char usage[] =
7942 "Syntax of the WINEDEBUG variable:\n"
7943 diff -urN wine-1.0/libs/wine/loader.c wine-1.0-uk/libs/wine/loader.c
7944 --- wine-1.0/libs/wine/loader.c 2008-06-17 22:07:31.000000000 +0800
7945 +++ wine-1.0-uk/libs/wine/loader.c 2009-08-18 16:11:13.000000000 +0800
7947 extern const char *get_dlldir( const char **default_dlldir );
7949 /* build the dll load path from the WINEDLLPATH variable */
7950 +#ifndef UNIFIED_KERNEL
7951 static void build_dll_path(void)
7953 +void build_dll_path(void)
7957 char *p, *path = getenv( "WINEDLLPATH" );
7958 @@ -321,7 +325,11 @@
7961 /* map a builtin dll in memory and fixup RVAs */
7962 +#ifndef UNIFIED_KERNEL_EXESO
7963 static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
7965 +void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
7969 IMAGE_DATA_DIRECTORY *dir;
7970 @@ -807,3 +815,10 @@
7975 +#ifdef UNIFIED_KERNEL_EXESO
7976 +IMAGE_NT_HEADERS **get_main_exe_ptr()
7978 + return (IMAGE_NT_HEADERS **)&main_exe;
7981 diff -urN wine-1.0/libs/wine/Makefile.in wine-1.0-uk/libs/wine/Makefile.in
7982 --- wine-1.0/libs/wine/Makefile.in 2008-06-17 22:07:31.000000000 +0800
7983 +++ wine-1.0-uk/libs/wine/Makefile.in 2009-08-18 16:11:13.000000000 +0800
7985 MODULE = libwine.$(LIBEXT)
7986 VERSCRIPT = $(SRCDIR)/wine.map
7987 EXTRALIBS = $(LIBPORT) @LIBDL@ @CRTLIBS@
7988 -DEFS = -D__WINESRC__ -DWINE_UNICODE_API=""
7989 +DEFS = -D__WINESRC__ -DWINE_UNICODE_API="" \
7990 + -DUNIFIED_KERNEL -DUNIFIED_KERNEL_EXESO
7994 diff -urN wine-1.0/libs/wine/mmap.c wine-1.0-uk/libs/wine/mmap.c
7995 --- wine-1.0/libs/wine/mmap.c 2008-06-17 22:07:31.000000000 +0800
7996 +++ wine-1.0-uk/libs/wine/mmap.c 2009-08-18 16:11:13.000000000 +0800
7997 @@ -312,6 +312,12 @@
7998 wine_mmap_add_reserved_area( NULL, dos_area_size );
8001 +#ifdef UNIFIED_KERNEL
8002 +void uk_reserve_dos_area(void)
8004 + reserve_dos_area();
8008 /***********************************************************************
8010 diff -urN wine-1.0/libs/wine/wine.map wine-1.0-uk/libs/wine/wine.map
8011 --- wine-1.0/libs/wine/wine.map 2008-06-17 22:07:31.000000000 +0800
8012 +++ wine-1.0-uk/libs/wine/wine.map 2009-08-18 16:11:13.000000000 +0800
8013 @@ -117,6 +117,13 @@
8023 + uk_reserve_dos_area;
8027 diff -urN wine-1.0/loader/glibc.c wine-1.0-uk/loader/glibc.c
8028 --- wine-1.0/loader/glibc.c 2008-06-17 22:07:31.000000000 +0800
8029 +++ wine-1.0-uk/loader/glibc.c 2009-08-18 16:11:13.000000000 +0800
8030 @@ -112,6 +112,32 @@
8034 +#ifdef UNIFIED_KERNEL
8035 +static void check_command_line( int argc, char *argv[] )
8037 + static const char usage[] =
8038 + "Usage: wine PROGRAM [ARGUMENTS...] Run the specified program\n"
8039 + " wine --help Display this help and exit\n"
8040 + " wine --version Output version information and exit";
8044 + fprintf( stderr, "%s\n", usage );
8047 + if (!strcmp( argv[1], "--help" ))
8049 + printf( "%s\n", usage);
8052 + if (!strcmp( argv[1], "--version" ))
8054 + printf( "%s\n", wine_get_build_id() );
8060 /**********************************************************************
8064 const char *threads = get_threading();
8065 const char *new_argv0 = build_new_path( argv[0], threads );
8067 +#ifdef UNIFIED_KERNEL
8068 + check_command_line( argc, argv );
8070 wine_init_argv0_path( new_argv0 );
8072 /* set the address space limit before starting the preloader */
8073 diff -urN wine-1.0/loader/Makefile.in wine-1.0-uk/loader/Makefile.in
8074 --- wine-1.0/loader/Makefile.in 2008-06-17 22:07:31.000000000 +0800
8075 +++ wine-1.0-uk/loader/Makefile.in 2009-08-18 16:11:13.000000000 +0800
8077 +DEFS = -DUNIFIED_KERNEL
8078 TOPSRCDIR = @top_srcdir@
8081 diff -urN wine-1.0/programs/explorer/explorer.c wine-1.0-uk/programs/explorer/explorer.c
8082 --- wine-1.0/programs/explorer/explorer.c 2008-06-17 22:07:31.000000000 +0800
8083 +++ wine-1.0-uk/programs/explorer/explorer.c 2009-08-18 16:11:13.000000000 +0800
8084 @@ -135,8 +135,23 @@
8088 +#ifndef UNIFIED_KERNEL /* resolve the problem that path with blank can't be opened */
8089 /* left over command line is generally the path to be opened */
8090 CopyPathString(parameters->root,p2);
8092 + LPWSTR quotationW = NULL;
8093 + int len = strlenW(p2);
8095 + quotationW = HeapAlloc(GetProcessHeap(), 0, (len + 3) * sizeof(WCHAR));
8097 + quotationW[0] = '\"';
8098 + strcpyW("ationW[1], p2);
8099 + quotationW[len + 1] = '\"';
8100 + quotationW[len + 2] = 0;
8101 + CopyPathString(parameters->root,quotationW);
8102 + HeapFree(GetProcessHeap(), 0, quotationW);
8108 diff -urN wine-1.0/programs/Makeprog.rules.in wine-1.0-uk/programs/Makeprog.rules.in
8109 --- wine-1.0/programs/Makeprog.rules.in 2008-06-17 22:07:31.000000000 +0800
8110 +++ wine-1.0-uk/programs/Makeprog.rules.in 2009-08-18 16:11:13.000000000 +0800
8114 DLLFLAGS = @DLLFLAGS@
8115 -DEFS = $(EXTRADEFS)
8116 +DEFS = $(EXTRADEFS) -DUNIFIED_KERNEL
8117 ALL_LIBS = $(DELAYIMPORTS:%=-l%) $(IMPORTS:%=-l%) $(EXTRALIBS) $(LIBPORT) $(LDFLAGS) $(LIBS)
8118 BASEMODULE = $(MODULE:.exe=)
8119 RUNTESTFLAGS= -q -P wine -T $(TOPOBJDIR)
8120 diff -urN wine-1.0/programs/services/services.c wine-1.0-uk/programs/services/services.c
8121 --- wine-1.0/programs/services/services.c 2008-06-17 22:07:31.000000000 +0800
8122 +++ wine-1.0-uk/programs/services/services.c 2009-08-18 16:11:13.000000000 +0800
8127 +#ifndef UNIFIED_KERNEL
8128 static DWORD service_start_process(struct service_entry *service_entry, HANDLE *process)
8130 PROCESS_INFORMATION pi;
8131 @@ -675,12 +676,15 @@
8137 DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *service_argv)
8141 +#ifndef UNIFIED_KERNEL
8142 HANDLE process_handle = NULL;
8145 err = scmdatabase_lock_startup(service->db);
8146 if (err != ERROR_SUCCESS)
8148 return GetLastError();
8151 +#ifndef UNIFIED_KERNEL
8152 err = service_start_process(service, &process_handle);
8154 if (err == ERROR_SUCCESS)
8158 CloseHandle(process_handle);
8161 ReleaseMutex(service->control_mutex);
8162 scmdatabase_unlock_startup(service->db);
8163 diff -urN wine-1.0/programs/winefile/winefile.c wine-1.0-uk/programs/winefile/winefile.c
8164 --- wine-1.0/programs/winefile/winefile.c 2008-06-17 22:07:31.000000000 +0800
8165 +++ wine-1.0-uk/programs/winefile/winefile.c 2009-08-18 16:11:13.000000000 +0800
8167 #include "winefile.h"
8168 #include "resource.h"
8170 +#ifdef UNIFIED_KERNEL
8171 +#include "wine/library.h"
8174 #ifdef _NO_EXTENSIONS
8177 @@ -3782,6 +3786,11 @@
8178 static void set_curdir(ChildWnd* child, Entry* entry, int idx, HWND hwnd)
8180 TCHAR path[MAX_PATH];
8181 +#ifdef UNIFIED_KERNEL
8182 + const char *config_dir = wine_get_config_dir();
8183 + char cmdline[MAX_PATH], ansi_path[MAX_PATH];
8189 @@ -3807,6 +3816,22 @@
8191 if (SetCurrentDirectory(path))
8194 +#ifdef UNIFIED_KERNEL
8195 + strcpy(cmdline, config_dir);
8196 + strcat(cmdline, "/dosdevices/");
8197 + WideCharToMultiByte(CP_UNIXCP, 0, path, -1, ansi_path, sizeof(ansi_path), NULL, NULL);
8198 + if (ansi_path[0] >= 0x0041 && ansi_path[0] <= 0x005a)
8199 + ansi_path[0] += 32;
8200 + for (i = 0; i < strlen(ansi_path); i++) {
8201 + if (ansi_path[i] == '\\')
8202 + ansi_path[i] = '/';
8204 + strcat(cmdline, ansi_path);
8205 + if (execl("/usr/bin/kfmclient", "kfmclient", "exec", cmdline, (char *)0) < 0) {
8206 + execl("/usr/bin/nautilus", "nautilus", cmdline, (char *)0);
8212 diff -urN wine-1.0/programs/winemenubuilder/winemenubuilder.c wine-1.0-uk/programs/winemenubuilder/winemenubuilder.c
8213 --- wine-1.0/programs/winemenubuilder/winemenubuilder.c 2008-06-17 22:07:31.000000000 +0800
8214 +++ wine-1.0-uk/programs/winemenubuilder/winemenubuilder.c 2009-08-18 16:11:13.000000000 +0800
8215 @@ -1180,7 +1180,12 @@
8218 /* escape the path and parameters */
8219 +#ifndef UNIFIED_KERNEL
8220 escaped_path = escape(szPath);
8222 + /* convert the path passed to wineshelllink into unix format */
8223 + escaped_path = wine_get_unix_file_name( szPath );
8225 escaped_args = escape(szArgs);
8226 escaped_description = escape(szDescription);
8228 diff -urN wine-1.0/server/Makefile.in wine-1.0-uk/server/Makefile.in
8229 --- wine-1.0/server/Makefile.in 2008-06-17 22:07:31.000000000 +0800
8230 +++ wine-1.0-uk/server/Makefile.in 2009-08-18 16:11:13.000000000 +0800
8232 -DEFS = -D__WINESRC__
8233 +DEFS = -D__WINESRC__ -DUNIFIED_KERNEL
8234 TOPSRCDIR = @top_srcdir@
8237 diff -urN wine-1.0/server/process.c wine-1.0-uk/server/process.c
8238 --- wine-1.0/server/process.c 2008-06-17 22:07:31.000000000 +0800
8239 +++ wine-1.0-uk/server/process.c 2009-08-18 16:11:13.000000000 +0800
8240 @@ -142,6 +142,12 @@
8241 unsigned int next; /* next free entry */
8244 +#ifdef UNIFIED_KERNEL
8245 +#define PTID_RESERVE_OFFSET 32
8246 +#define PTID_TO_INDEX(id) ((id >> 2) - PTID_RESERVE_OFFSET)
8247 +#define INDEX_TO_PTID(index) ((index + PTID_RESERVE_OFFSET) << 2)
8250 static struct ptid_entry *ptid_entries; /* array of ptid entries */
8251 static unsigned int used_ptid_entries; /* number of entries in use */
8252 static unsigned int alloc_ptid_entries; /* number of allocated entries */
8253 @@ -188,9 +194,42 @@
8257 +#ifdef UNIFIED_KERNEL
8260 + * Store the pid/tid we get from the client.
8261 + * - The only thing we should care is that
8262 + * - a pid/tid is created linearly.
8264 +int store_ptid(unsigned int id, void *ptr)
8266 + struct ptid_entry *entry;
8267 + unsigned int index = PTID_TO_INDEX(id);
8269 + if (index < alloc_ptid_entries)
8270 + entry = &ptid_entries[index];
8273 + unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2);
8276 + if (!(entry = realloc(ptid_entries, count * sizeof(*entry))))
8279 + ptid_entries = entry;
8280 + alloc_ptid_entries = count;
8281 + entry = &ptid_entries[index];
8283 + used_ptid_entries++;
8289 /* free a process or thread id */
8290 void free_ptid( unsigned int id )
8292 +#ifndef UNIFIED_KERNEL
8293 struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];
8296 @@ -201,14 +240,28 @@
8297 else next_free_ptid = id;
8299 last_free_ptid = id;
8301 + struct ptid_entry *entry = &ptid_entries[PTID_TO_INDEX(id)];
8303 + entry->ptr = NULL;
8305 + used_ptid_entries--;
8309 /* retrieve the pointer corresponding to a process or thread id */
8310 void *get_ptid_entry( unsigned int id )
8312 +#ifndef UNIFIED_KERNEL
8313 if (id < PTID_OFFSET) return NULL;
8314 if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
8315 return ptid_entries[id - PTID_OFFSET].ptr;
8317 + int index = PTID_TO_INDEX(id);
8318 + if ((id % 4) || (index <= 0))
8320 + return ptid_entries[index].ptr;
8324 /* return the main thread of the process */
8325 @@ -346,11 +399,15 @@
8326 process->end_time = 0;
8327 list_add_tail( &process_list, &process->entry );
8329 +#ifndef UNIFIED_KERNEL
8330 if (!(process->id = process->group_id = alloc_ptid( process )))
8336 + process->id = process->group_id = 0;
8338 if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj, 0 ))) goto error;
8340 /* create the handle table */
8342 list_remove( &process->entry );
8343 if (process->idle_event) release_object( process->idle_event );
8344 if (process->queue) release_object( process->queue );
8345 +#ifndef UNIFIED_KERNEL
8346 if (process->id) free_ptid( process->id );
8348 if (process->token) release_object( process->token );
8352 if (thread == skip) break;
8353 kill_thread( thread, 1 );
8355 +#ifdef UNIFIED_KERNEL
8356 + if (process->id) free_ptid( process->id );
8358 release_object( process );
8362 struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
8363 kill_thread( thread, 0 );
8365 +#ifdef UNIFIED_KERNEL
8366 + if (process->id) free_ptid( process->id );
8368 release_object( process );
8371 @@ -970,8 +1035,10 @@
8373 info->process = (struct process *)grab_object( process );
8374 reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
8375 +#ifndef UNIFIED_KERNEL
8376 reply->pid = get_process_id( process );
8377 reply->tid = get_thread_id( thread );
8379 reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr );
8380 reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
8382 @@ -1042,7 +1109,9 @@
8383 set_process_startup_state( process, STARTUP_DONE );
8385 if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL );
8386 +#ifndef UNIFIED_KERNEL
8387 if (current->suspend + process->suspend > 0) stop_thread( current );
8389 if (process->debugger) set_process_debug_flag( process, 1 );
8392 diff -urN wine-1.0/server/thread.c wine-1.0-uk/server/thread.c
8393 --- wine-1.0/server/thread.c 2008-06-17 22:07:31.000000000 +0800
8394 +++ wine-1.0-uk/server/thread.c 2009-08-19 11:05:05.000000000 +0800
8396 #include "security.h"
8399 +#ifdef UNIFIED_KERNEL
8400 +extern int store_ptid(unsigned int id, void *ptr);
8406 @@ -208,11 +212,15 @@
8408 list_add_head( &thread_list, &thread->entry );
8410 +#ifndef UNIFIED_KERNEL
8411 if (!(thread->id = alloc_ptid( thread )))
8413 release_object( thread );
8419 if (!(thread->request_fd = create_anonymous_fd( &thread_fd_ops, fd, &thread->obj, 0 )))
8421 release_object( thread );
8423 list_remove( &thread->entry );
8424 cleanup_thread( thread );
8425 release_object( thread->process );
8426 +#ifndef UNIFIED_KERNEL
8427 if (thread->id) free_ptid( thread->id );
8429 if (thread->token) release_object( thread->token );
8432 @@ -432,7 +442,11 @@
8433 int old_count = thread->suspend;
8434 if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
8436 +#ifndef UNIFIED_KERNEL
8437 if (!(thread->process->suspend + thread->suspend++)) stop_thread( thread );
8439 + thread->suspend++;
8442 else set_error( STATUS_SUSPEND_COUNT_EXCEEDED );
8444 @@ -444,7 +458,11 @@
8445 int old_count = thread->suspend;
8446 if (thread->suspend > 0)
8448 +#ifndef UNIFIED_KERNEL
8449 if (!(--thread->suspend + thread->process->suspend)) wake_thread( thread );
8451 + thread->suspend--;
8456 @@ -916,17 +934,24 @@
8459 while (thread->wait) end_wait( thread );
8460 +#ifndef UNIFIED_KERNEL
8461 send_thread_wakeup( thread, NULL, STATUS_PENDING );
8462 /* if it is waiting on the socket, we don't need to send a SIGQUIT */
8466 kill_console_processes( thread, 0 );
8467 +#ifndef UNIFIED_KERNEL
8468 debug_exit_thread( thread );
8469 abandon_mutexes( thread );
8470 wake_up( &thread->obj, 0 );
8471 if (violent_death) send_thread_signal( thread, SIGQUIT );
8473 cleanup_thread( thread );
8474 remove_process_thread( thread->process, thread );
8475 +#ifdef UNIFIED_KERNEL
8476 + if (thread->id && violent_death) free_ptid( thread->id );
8478 release_object( thread );
8481 @@ -995,6 +1020,12 @@
8483 if ((thread = create_thread( request_fd, current->process )))
8485 +#ifdef UNIFIED_KERNEL
8487 + thread->id = req->tid;
8488 + store_ptid(thread->id, thread);
8491 if (req->suspend) thread->suspend++;
8492 reply->tid = get_thread_id( thread );
8493 if ((reply->handle = alloc_handle( current->process, thread, req->access, req->attributes )))
8494 @@ -1042,6 +1073,17 @@
8495 current->unix_pid = req->unix_pid;
8496 current->unix_tid = req->unix_tid;
8497 current->teb = req->teb;
8498 +#ifdef UNIFIED_KERNEL
8499 + /* We use the pid/tid allocated from kernel, and store it in the server */
8500 + if (!(current->id) && !(process->id)) {
8501 + /* If this request doesn't come from the procedure of process creating,
8502 + * it will never be here. */
8503 + process->group_id = process->id = req->pid;
8504 + current->id = req->tid;
8505 + store_ptid(process->id, process);
8506 + store_ptid(current->id, current);
8510 if (!process->peb) /* first thread, initialize the process too */
8512 @@ -1054,7 +1096,9 @@
8514 if (process->unix_pid != current->unix_pid)
8515 process->unix_pid = -1; /* can happen with linuxthreads */
8516 +#ifndef UNIFIED_KERNEL
8517 if (current->suspend + process->suspend > 0) stop_thread( current );
8519 generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry );
8521 debug_level = max( debug_level, req->debug_level );
8522 @@ -1085,6 +1129,9 @@
8525 reply->last = (thread->process->running_threads == 1);
8526 +#ifdef UNIFIED_KERNEL
8527 + if (thread->id) free_ptid( thread->id );
8530 release_object( thread );
8532 diff -urN wine-1.0/tools/wineshelllink wine-1.0-uk/tools/wineshelllink
8533 --- wine-1.0/tools/wineshelllink 2008-06-17 22:07:31.000000000 +0800
8534 +++ wine-1.0-uk/tools/wineshelllink 2009-08-18 16:11:13.000000000 +0800
8539 -Exec=env WINEPREFIX="${WINEPREFIX:-$HOME/.wine}" wine "$path" $args