updated on Wed Jan 18 20:10:41 UTC 2012
[aur-mirror.git] / longene-wine / longene.patch
blob7fbd26552b7403fc07ea27dc0e4dd1acdbefe9c9
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
4 @@ -574,7 +574,7 @@
5 # Identity of this package.
6 PACKAGE_NAME='Wine'
7 PACKAGE_TARNAME='wine'
8 -PACKAGE_VERSION='1.0'
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
16 @@ -443,4 +443,14 @@
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)"
26 + IDS_SAVE "±£´æ"
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();
45 +#endif
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();
60 +#endif
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();
75 +#endif
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();
90 +#endif
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
97 @@ -35,6 +35,9 @@
98 #include "gdi_private.h"
99 #include "wine/unicode.h"
100 #include "wine/debug.h"
101 +#ifdef UNIFIED_KERNEL
102 +#include <wchar.h>
103 +#endif
105 WINE_DEFAULT_DEBUG_CHANNEL(font);
107 @@ -1563,7 +1566,11 @@
108 LPINT lpDxW = NULL;
110 if (flags & ETO_GLYPH_INDEX)
111 +#ifdef UNIFIED_KERNEL
112 + return ExtTextOutW( hdc, x, y, flags, lprect, (LPWSTR)str, count, lpDx );
113 +#else
114 return ExtTextOutW( hdc, x, y, flags, lprect, (LPCWSTR)str, count, lpDx );
115 +#endif
117 p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
119 @@ -1620,8 +1627,13 @@
120 * Success: TRUE
121 * Failure: FALSE
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 )
126 +#else
127 +BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
128 + const RECT *lprect, LPWSTR str, UINT count, const INT *lpDx )
129 +#endif
131 BOOL ret = FALSE;
132 LPWSTR reordered_str = (LPWSTR)str;
133 @@ -1640,6 +1652,102 @@
134 DC * dc = get_dc_ptr( hdc );
135 INT breakRem;
137 +#ifdef UNIFIED_KERNEL
138 + HFONT hfOld = 0;
139 + double arc = 0;
140 + BOOL bAtFont;
141 + UINT prev_align = align;
142 + int i;
144 + if (!dc) return FALSE;
146 + if ((INT)count == -1)
147 + count = strlenW(str);
149 + if (align == TA_BASELINE) {
150 + TEXTMETRICW tmw;
151 + LOGFONTW lf;
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;
166 + else
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 */
177 + bAtFont = FALSE;
180 + if(bAtFont) {
181 + LOGFONTW lf;
182 + HFONT hf;
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++) {
189 + switch(str[i]) {
190 + case 0x201c: /* "(left) */
191 + str[i] = 0xfe43;
192 + break;
193 + case 0x201d: /* "(right) */
194 + str[i] = 0xfe44;
195 + break;
196 + case 0x2018: /* '(left) */
197 + str[i] = 0xfe41;
198 + break;
199 + case 0x2019: /*'(right) */
200 + str[i] = 0xfe42;
201 + break;
202 + case 0x300a: /* << */
203 + str[i] = 0xfe3d;
204 + break;
205 + case 0x300b: /* >> */
206 + str[i] = 0xfe3e;
207 + break;
208 + default:
209 + break;
212 + lfCloneFromDC(dc, &lf);
214 + hf = CreateFontIndirectW(&lf);
215 + hfOld = SelectObject(hdc, hf);
216 + GetRotate(dc, lf);
218 + switch (align) {
219 + case TA_TOP:
221 + TEXTMETRICW tm;
223 + GetTextMetricsW(hdc, &tm);
224 + x += sin(arc2) * tm.tmHeight;
225 + y += cos(arc2) * tm.tmHeight;
226 + break;
228 + default:
229 + break;
232 +#endif
233 if (!dc) return FALSE;
235 breakRem = dc->breakRem;
236 @@ -2067,6 +2175,12 @@
240 +#ifdef UNIFIED_KERNEL
241 + if (hfOld)
242 + SelectObject(hdc, hfOld);
243 + SetTextAlign(hdc, prev_align);
244 +#endif
246 return ret;
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 );
255 +#else
256 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
257 +#endif
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 ))
268 +#else
269 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
270 +#endif
271 return FALSE;
272 return TRUE;
274 @@ -2348,9 +2471,31 @@
276 if(!dc) return GDI_ERROR;
278 +#ifdef UNIFIED_KERNEL
279 + if (dc->gdiFont && font_is_italic(dc->gdiFont)) {
280 + MAT2 mat;
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;
288 + if (lpmat2)
289 + ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
290 + cbBuffer, lpBuffer, lpmat2);
291 + else
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);
298 +#else
299 if(dc->gdiFont)
300 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
301 cbBuffer, lpBuffer, lpmat2);
302 +#endif
303 else
304 ret = GDI_ERROR;
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
309 @@ -36,6 +36,9 @@
310 #include <dirent.h>
311 #include <stdio.h>
312 #include <assert.h>
313 +#ifdef UNIFIED_KERNEL
314 +#include <wchar.h>
315 +#endif
317 #ifdef HAVE_CARBON_CARBON_H
318 #define LoadResource __carbon_LoadResource
319 @@ -163,7 +166,11 @@
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
325 +#else
326 MAKE_FUNCPTR(FT_MulFix);
327 +#endif
328 MAKE_FUNCPTR(FT_New_Face);
329 MAKE_FUNCPTR(FT_New_Memory_Face);
330 MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
331 @@ -323,6 +330,9 @@
332 int codepage;
333 BOOL fake_italic;
334 BOOL fake_bold;
335 +#ifdef UNIFIED_KERNEL
336 + BOOL rotate;
337 +#endif
338 BYTE underline;
339 BYTE strikeout;
340 INT orientation;
341 @@ -470,6 +480,66 @@
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)
365 + return;
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 */
381 + int i=1;
382 + while(sourlf->lfFaceName[i])
384 + lf->lfFaceName[i] = sourlf->lfFaceName[i];
385 + i++;
387 + lf->lfFaceName[i] = 0x0;
389 + else
391 + strcpyW(lf->lfFaceName, sourlf->lfFaceName);
393 +#if 0
394 + FindEnFontName(lf->lfFaceName);
395 +#endif
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;
404 +#endif
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)
414 +#endif
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 @@
420 ret = alloc_font();
422 +#ifdef UNIFIED_KERNEL
423 + if (lf.lfFaceName[0] != '\0' && lf.lfFaceName[0] == 0x0040)
424 + ret->rotate = TRUE;
425 +#endif
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;
438 - break;
439 - default:
440 - FIXME("Untranslated charset %d\n", lf.lfCharSet);
441 - csi.fs.fsCsb[0] = 0;
442 - break;
445 +#else
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)) {
450 +#endif
451 + switch(lf.lfCharSet) {
452 + case DEFAULT_CHARSET:
453 + csi.fs.fsCsb[0] = 0;
454 + break;
455 + default:
456 + FIXME("Untranslated charset %d\n", lf.lfCharSet);
457 + csi.fs.fsCsb[0] = 0;
458 + break;
462 family = NULL;
463 if(lf.lfFaceName[0] != '\0') {
464 @@ -4262,10 +4345,20 @@
465 if (font->fake_italic) {
466 FT_Matrix slantMat;
468 +#ifndef UNIFIED_KERNEL
469 slantMat.xx = (1 << 16);
470 slantMat.xy = ((1 << 16) >> 2);
471 slantMat.yx = 0;
472 slantMat.yy = (1 << 16);
473 +#else
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);
481 +#endif
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
488 @@ -515,6 +515,14 @@
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);
499 +#endif
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
506 @@ -913,7 +913,11 @@
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);
512 +#else
513 LPSTR bits = (LPSTR)info + bitmap_info_size( info, mr->rdParm[2] );
514 +#endif
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
521 @@ -27,6 +27,9 @@
522 #include "kernel_private.h"
523 #include "kernel16_private.h"
524 #include "wine/debug.h"
525 +#ifdef UNIFIED_KERNEL
526 +#include "handle.h"
527 +#endif
529 WINE_DEFAULT_DEBUG_CHANNEL(debugstr);
531 @@ -325,6 +328,11 @@
533 TRACE("(%p)\n", hProc);
535 +#ifdef UNIFIED_KERNEL
536 + struct handle_pair* pair = search_handle_pair(hProc);
537 + if (pair)
538 + hProc= pair->wine_handle;
539 +#endif
540 SERVER_START_REQ( debug_break )
542 req->handle = hProc;
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
546 @@ -163,6 +163,7 @@
547 void *addr = NULL;
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)
554 @@ -207,6 +208,7 @@
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 );
558 +#endif
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
565 @@ -52,6 +52,10 @@
566 #include "wine/unicode.h"
567 #include "wine/debug.h"
569 +#ifdef UNIFIED_KERNEL
570 +#include "handle.h"
571 +#endif
573 WINE_DEFAULT_DEBUG_CHANNEL(process);
574 WINE_DECLARE_DEBUG_CHANNEL(file);
575 WINE_DECLARE_DEBUG_CHANNEL(relay);
576 @@ -157,6 +161,7 @@
580 +#ifndef UNIFIED_KERNEL
581 /***********************************************************************
582 * open_builtin_exe_file
584 @@ -184,6 +189,7 @@
586 return wine_dll_load_main_exe( exename, error, error_size, test_only, file_exists );
588 +#endif
591 /***********************************************************************
592 @@ -215,6 +221,7 @@
596 +#ifndef UNIFIED_KERNEL
597 /***********************************************************************
598 * find_exe_file
600 @@ -260,6 +267,7 @@
602 return FALSE;
604 +#endif
607 /***********************************************************************
608 @@ -581,8 +589,10 @@
610 argv[argc] = NULL;
612 +#ifndef UNIFIED_KERNEL
613 __wine_main_argc = argc;
614 __wine_main_argv = argv;
615 +#endif
616 __wine_main_wargv = wargv;
619 @@ -877,6 +887,63 @@
620 return event;
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,
627 + * so here it is.
628 + */
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);
643 + LOCALE_Init();
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( &params->CurrentDirectory );
660 + /* start wineboot */
661 + if (!(*psocketfd))
662 + boot_event = start_wineboot();
664 + if (boot_event)
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);
677 + return TRUE;
679 +#endif
681 /***********************************************************************
682 * start_process
683 @@ -1168,6 +1235,7 @@
687 +#ifndef UNIFIED_KERNEL
688 /***********************************************************************
689 * alloc_env_string
691 @@ -1291,6 +1359,7 @@
692 close( fd[0] );
693 return pid;
695 +#endif
698 /***********************************************************************
699 @@ -1592,6 +1661,7 @@
703 +#ifndef UNIFIED_KERNEL
704 /***********************************************************************
705 * create_cmd_process
707 @@ -1711,6 +1781,7 @@
708 HeapFree( GetProcessHeap(), 0, name );
709 return ret;
711 +#endif
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 );
725 return retv;
727 +#endif
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,
747 + IN ULONG Length,
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);
763 +NTSTATUS WINAPI
764 +UkOpenFile( PHANDLE handle, ACCESS_MASK access,
765 + POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
766 + ULONG sharing, ULONG options );
768 +NTSTATUS WINAPI
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;
780 + DWORD size;
781 + BYTE buffer[sizeof(*dos) + sizeof(fakedll_signature)];
783 + if (!ReadFile( h, buffer, sizeof(buffer), &size, NULL ) || size != sizeof(buffer))
784 + return FALSE;
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)
793 + HANDLE handle;
795 + handle = CreateFileW(AppName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
796 + if (handle == INVALID_HANDLE_VALUE)
797 + return FALSE;
798 + if (IsFakeDll(handle)) {
799 + CloseHandle(handle);
800 + return FALSE;
802 + CloseHandle(handle);
803 + return TRUE;
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;
812 + char *c;
813 + char name[MAX_PATH];
814 + int len;
815 + WCHAR *p;
816 + struct stat stat_buf;
818 + p = strrchrW(Native, '\\');
819 + if (p)
820 + p++;
821 + else
822 + p = Native;
824 + get_dlldir(&prefix);
826 + len = strlen(prefix);
827 + memcpy(name, prefix, len);
828 + name[len++] = '/';
829 + WideCharToMultiByte(CP_UNIXCP, 0, p, strlenW(p) + 1, name + len, sizeof(name) - len, 0, NULL);
831 + c = name + len;
832 + while (*c) {
833 + *c = tolower(*c);
834 + c++;
837 + len = c - name;
838 + if (strcasecmp(name + len - 4, ".exe")) {
839 + memcpy(name + len, ".exe.so", sizeof(".exe.so"));
840 + len += sizeof(".exe.so") - 1;
842 + else {
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);
849 + return TRUE;
851 + return FALSE;
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)) {
865 + Found = TRUE;
866 + *UseNative = FALSE;
868 + } else {
869 + Found = TRUE;
870 + *UseNative = TRUE;
872 + } else {
873 + if (NativeToBuiltin(AppName, BuiltinAppName, BuiltinAppNameLen)) {
874 + Found = TRUE;
875 + *UseNative = FALSE;
879 + return Found;
882 +static inline void MakeBuiltinCmdLine(LPWSTR CmdLine, LPWSTR AppName, LPWSTR Params)
884 + WCHAR Quotation[] = {L'\"', 0};
886 + CmdLine[0] = L'"';
887 + strcpyW(CmdLine + 1, AppName);
888 + strcatW(CmdLine, Quotation);
889 + if (Params)
890 + strcatW(CmdLine, Params);
893 +#else
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))
903 + return TRUE;
905 + return FALSE;
908 +#endif
911 + * GetFileName
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
920 + */
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;
927 + const WCHAR *p;
929 + /* if we have an app name, everything is easy */
930 + if (AppName) {
931 + if (!SearchApplication((LPWSTR)AppName, Buffer, BufLen, BuiltinAppName,
932 + BuiltinAppNameLen, &UseNative)) {
933 + SetLastError(ERROR_FILE_NOT_FOUND);
934 + return NULL;
937 + /* use the unmodified app name as file name */
938 + if (!UseNative)
939 + lstrcpynW(Buffer, AppName, BufLen );
940 + Ret = CmdLine;
941 + if (!Ret || !CmdLine[0]) {
942 + /* no command-line, create one */
943 + Ret = RtlAllocateHeap(GetProcessHeap(), 0,
944 + (strlenW(Buffer) + 3) * sizeof(WCHAR));
945 + if (Ret) {
946 + Ret[0] = L'"';
947 + strcpyW(Ret + 1, Buffer);
948 + strcatW(Ret, Quotation);
951 +#ifdef UNIFIED_KERNEL_EXESO
952 + if (!UseNative)
953 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, NULL);
954 +#endif
955 + return Ret;
958 + if (!CmdLine) {
959 + SetLastError(ERROR_INVALID_PARAMETER);
960 + return NULL;
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));
969 + if (!Name) {
970 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
971 + return NULL;
973 + memcpy(Name, CmdLine + 1, Len * sizeof(WCHAR));
974 + Name[Len] = L'\0';
976 + if (!SearchApplication(Name, Buffer, BufLen, BuiltinAppName, BuiltinAppNameLen, &UseNative)) {
977 + RtlFreeHeap(GetProcessHeap(), 0, Name);
978 + SetLastError(ERROR_FILE_NOT_FOUND);
979 + return NULL;
982 + if (!UseNative)
983 + memcpy(Buffer, Name, Len * sizeof(WCHAR) + sizeof(WCHAR));
984 + strcpyW(Name, ++p); /* backup param */
985 + Ret = CmdLine;
986 + Ret[0] = L'"';
987 + strcpyW(Ret + 1, Buffer);
988 + strcatW(Ret, Quotation);
989 + strcatW(Ret, Name);
991 +#ifdef UNIFIED_KERNEL_EXESO
992 + if (!UseNative)
993 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, (LPWSTR)++p);
994 +#endif
996 + RtlFreeHeap(GetProcessHeap(), 0, Name);
997 + return Ret;
1000 + /* now try the command-line word by word */
1001 + Name = RtlAllocateHeap(GetProcessHeap(), 0, (strlenW(CmdLine) + 1) * sizeof(WCHAR));
1002 + if (!Name) {
1003 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1004 + return NULL;
1006 + Pos = Name;
1007 + p = CmdLine;
1009 + while (*p) {
1010 + do
1011 + *Pos++ = *p++;
1012 + while (*p && L' ' != *p);
1013 + *Pos = 0;
1015 + if (!SearchApplication(Name, Buffer, BufLen, BuiltinAppName, BuiltinAppNameLen, &UseNative))
1016 + continue;
1018 + if (!UseNative)
1019 + strcpyW(Buffer, Name);
1020 + Ret = CmdLine;
1022 +#ifdef UNIFIED_KERNEL_EXESO
1023 + if (!UseNative)
1024 + MakeBuiltinCmdLine(BuiltinCmdLine, BuiltinAppName, (LPWSTR)p);
1025 +#endif
1026 + break;
1029 + if (!Ret) {
1030 + RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
1031 + return Ret;
1034 + /* now build a new command-line with quotes */
1035 + Ret = RtlAllocateHeap(GetProcessHeap(), 0, (strlenW(CmdLine) + 3 + strlenW(Buffer)) * sizeof(WCHAR));
1036 + if (!Ret) {
1037 + RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
1038 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1039 + return NULL;
1041 + Ret[0] = L'"';
1042 + strcpyW(Ret + 1, Buffer);
1043 + strcatW(Ret, Quotation);
1044 + strcatW(Ret, p);
1046 + RtlFreeHeap(GetProcessHeap(), 0, Name);
1047 + return Ret;
1050 +/* modified from ReactOS */
1051 +HANDLE KlMapFile(LPCWSTR lpApplicationName)
1053 + HANDLE hFile;
1054 + IO_STATUS_BLOCK IoStatusBlock;
1055 + UNICODE_STRING ApplicationNameString;
1056 + OBJECT_ATTRIBUTES ObjectAttributes;
1057 + PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
1058 + NTSTATUS Status;
1059 + HANDLE hSection;
1061 + hFile = NULL;
1063 + if (!RtlDosPathNameToNtPathName_U(lpApplicationName, &ApplicationNameString, NULL, NULL)) {
1064 + SetLastError(ERROR_PATH_NOT_FOUND);
1065 + return NULL;
1067 + InitializeObjectAttributes(&ObjectAttributes,
1068 + &ApplicationNameString,
1069 + OBJ_CASE_INSENSITIVE,
1070 + NULL,
1071 + SecurityDescriptor);
1073 + /* Try to open the executable */
1075 + Status = UkOpenFile(&hFile,
1076 + SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
1077 + &ObjectAttributes,
1078 + &IoStatusBlock,
1079 + FILE_SHARE_DELETE|FILE_SHARE_READ,
1080 + FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
1082 + RtlFreeUnicodeString (&ApplicationNameString);
1084 + if (Status) {
1085 + SetLastError(Status);
1086 + return NULL;
1088 + Status = UkCreateSection(&hSection,
1089 + SECTION_ALL_ACCESS,
1090 + NULL,
1091 + NULL,
1092 + PAGE_EXECUTE,
1093 + SEC_IMAGE,
1094 + hFile);
1095 + NtClose(hFile);
1097 + if (Status) {
1098 + SetLastError(Status);
1099 + return NULL;
1102 + return hSection;
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;
1117 + HANDLE hThread;
1119 + /* convert the thread attributes */
1120 + RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes);
1122 + /* native image */
1123 + if(Sii->ImageSubsystem != IMAGE_SUBSYSTEM_NATIVE)
1124 + pTrueStartAddress = NULL;
1125 + /* Win32 image */
1126 + /* FIXME: nothing to do with win32 image */
1127 + else
1128 + ERR("Nothing to do with Win32 image!\n");
1130 + /* create the first thread */
1131 + nErrCode = RtlRosCreateUserThread(ProcessHandle,
1132 + &oaThreadAttribs,
1133 + dwCreationFlags & CREATE_SUSPENDED,
1134 + 0,
1135 + &(Sii->StackReserved),
1136 + &(Sii->StackCommit),
1137 + pTrueStartAddress,
1138 + &hThread,
1139 + &cidClientId,
1140 + (ULONG_PTR)lpStartAddress,
1141 + (ULONG_PTR)PEB_BASE);
1142 + /* failure */
1143 + if(nErrCode) {
1144 + SetLastError(nErrCode);
1145 + return NULL;
1148 + /* success */
1149 + if(lpThreadId)
1150 + *lpThreadId = (DWORD)cidClientId.UniqueThread;
1152 + return hThread;
1155 +static NTSTATUS KlInitPeb(HANDLE ProcessHandle,
1156 + PRTL_USER_PROCESS_PARAMETERS Ppb,
1157 + PVOID * ImageBaseAddress,
1158 + ULONG ImageSubSystem)
1160 + PWCHAR ptr;
1161 + PVOID EnvPtr = NULL;
1162 + PVOID ParentEnv = NULL;
1163 + PVOID PpbBase = NULL;
1164 + ULONG offset = 0;
1165 + ULONG_PTR EnvSize = 0, PpbSize = 0;
1166 + ULONG_PTR EnvSize1 = 0;
1167 + ULONG_PTR ByteWritten = 0;
1168 + ULONG peb_base = 0x7FFDF000;
1169 + NTSTATUS Status;
1171 + if (Ppb->Environment) {
1172 + ptr = Ppb->Environment;
1173 + while (*ptr)
1174 + while (*ptr++);
1175 + ptr++;
1176 + EnvSize = ((ULONG)ptr - (ULONG)Ppb->Environment);
1177 + ParentEnv = Ppb->Environment;
1180 + if (EnvSize != 0) {
1181 + EnvSize1 = EnvSize;
1182 + Status = NtAllocateVirtualMemory(ProcessHandle,
1183 + &EnvPtr,
1184 + 0,
1185 + &EnvSize1,
1186 + MEM_COMMIT,
1187 + PAGE_READWRITE);
1188 + if (Status) {
1189 + return(Status);
1192 + NtWriteVirtualMemory(ProcessHandle,
1193 + EnvPtr,
1194 + ParentEnv,
1195 + EnvSize,
1196 + &ByteWritten);
1199 + /* create ppb in child space*/
1200 + PpbSize = Ppb->AllocationSize;
1202 + Status = NtAllocateVirtualMemory(ProcessHandle,
1203 + &PpbBase,
1204 + 0,
1205 + &PpbSize,
1206 + MEM_COMMIT,
1207 + PAGE_READWRITE);
1208 + if (Status)
1209 + return Status;
1211 + NtWriteVirtualMemory(ProcessHandle,
1212 + PpbBase,
1213 + Ppb,
1214 + PpbSize,
1215 + &ByteWritten);
1217 + /* write environment */
1218 + offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
1219 + NtWriteVirtualMemory(ProcessHandle,
1220 + (PVOID)((ULONG)PpbBase + offset),
1221 + &EnvPtr,
1222 + sizeof(EnvPtr),
1223 + &ByteWritten);
1225 + /* write point to ppb */
1226 + offset = FIELD_OFFSET(PEB, ProcessParameters);
1227 + NtWriteVirtualMemory(ProcessHandle,
1228 + (PVOID)(peb_base + offset),
1229 + &PpbBase,
1230 + sizeof(PpbBase),
1231 + &ByteWritten);
1233 + /* FIXME: write image subsystem ? */
1234 + offset = FIELD_OFFSET(PEB, ImageSubSystem);
1235 + NtWriteVirtualMemory(ProcessHandle,
1236 + (PVOID)(peb_base + offset),
1237 + &ImageSubSystem,
1238 + sizeof(ImageSubSystem),
1239 + &ByteWritten);
1241 + /* read image base address */
1242 + offset = FIELD_OFFSET(PEB, ImageBaseAddress);
1243 + NtReadVirtualMemory(ProcessHandle,
1244 + (PVOID)(peb_base + offset),
1245 + ImageBaseAddress,
1246 + sizeof(PVOID),
1247 + &ByteWritten);
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;
1267 + pid_t pid;
1268 + int socketfd[2];
1269 + int pipefd[2];
1270 + HANDLE process_info;
1271 + NTSTATUS Status;
1272 + BOOL success = FALSE;
1273 + CLIENT_ID cid;
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 );
1279 + return FALSE;
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;
1305 + } else {
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;
1327 + SERVER_END_REQ;
1329 + if (Status) {
1330 + close(socketfd[0]);
1331 + return FALSE;
1334 + if (pipe(pipefd) == -1) {
1335 + close(socketfd[0]);
1336 + return FALSE;
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);
1346 + close(pipefd[0]);
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);
1356 + putenv(pipe_env);
1357 + putenv(app_env);
1358 + putenv(cmdline_env);
1359 + if (argv)
1360 + wine_exec_wine_binary(0, argv, getenv("WINELOADER"));
1361 + _exit(1);
1364 + close(socketfd[0]);
1365 + close(pipefd[1]);
1366 + if (pid == -1) {
1367 + CloseHandle(process_info);
1368 + close(pipefd[0]);
1369 + return FALSE;
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;
1380 + SERVER_END_REQ;
1382 + CloseHandle(process_info);
1383 + if (success) {
1384 + read(pipefd[0], &lpProcessInformation->dwProcessId, sizeof(lpProcessInformation->dwProcessId));
1385 + read(pipefd[0], &lpProcessInformation->dwThreadId, sizeof(lpProcessInformation->dwThreadId));
1386 + }else {
1387 + close(pipefd[0]);
1388 + return FALSE;
1391 + close(pipefd[0]);
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);
1398 + if(Status)
1399 + return FALSE;
1400 + Status = NtOpenThread(&lpProcessInformation->hThread, THREAD_ALL_ACCESS, &attr, &cid);
1401 + if(Status) {
1402 + NtClose(lpProcessInformation->hProcess);
1403 + return FALSE;
1406 + return TRUE;
1408 +#endif
1410 + void
1411 +GetFullCmdLine(LPWSTR lpCommandLine)
1413 + WCHAR *cmdline = lpCommandLine;
1414 + /* FIXME */
1415 + WCHAR short_cmd[1024], long_cmd[1024], remain[1024];
1416 + WCHAR *temp;
1417 + int i;
1419 + if (*lpCommandLine == L'"') {
1420 + strcpyW(short_cmd, lpCommandLine + 1);
1421 + temp = strchrW(short_cmd, L'"');
1422 + if (temp) {
1423 + strcpyW(remain, temp);
1424 + *temp = L'\0';
1427 + /* FIXME */
1428 + if (!GetLongPathNameW(short_cmd, long_cmd, 1024)) {
1429 + lstrcpynW(long_cmd, short_cmd, 1024);
1431 + *cmdline++ = L'"';
1432 + } else {
1433 + strcpyW(short_cmd, lpCommandLine);
1434 + temp = strchrW(short_cmd, L' ');
1435 + if (temp) {
1436 + strcpyW(remain, temp);
1437 + *temp = L'\0';
1439 + else{
1440 + return;
1443 + /* FIXME */
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')
1452 + break;
1454 + *cmdline = L'\0';
1456 + strcatW(lpCommandLine, remain);
1459 + BOOL WINAPI
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;
1478 + int socketfd[2];
1480 + WCHAR* TidyCmdLine;
1481 + WCHAR Name[MAX_PATH];
1482 + WCHAR* TempCurrentDirectory;
1483 + WCHAR TempApplicationName[256];
1484 + WCHAR* tmp;
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;
1499 + NTSTATUS Status;
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,
1506 + bInheritHandles,
1507 + dwCreationFlags,
1508 + lpEnvironment,
1509 + lpCurrentDirectory,
1510 + lpStartupInfo,
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));
1523 + if (!TidyCmdLine)
1524 + return FALSE;
1525 +#ifdef UNIFIED_KERNEL_EXESO
1526 + if (*BuiltinAppName && *BuiltinCmdLine) {
1527 + return RunBuiltinApp(BuiltinAppName,
1528 + BuiltinCmdLine,
1529 + Name,
1530 + FullCmdLine,
1531 + lpProcessAttributes,
1532 + lpThreadAttributes,
1533 + bInheritHandles,
1534 + dwCreationFlags,
1535 + lpEnvironment,
1536 + lpCurrentDirectory,
1537 + lpStartupInfo,
1538 + lpProcessInformation);
1540 +#endif
1542 + /* deal with file name */
1543 + if (lpApplicationName && lpApplicationName[0])
1544 + strcpyW(TempApplicationName, lpApplicationName);
1545 + else {
1546 + if (L'"' == TidyCmdLine[0]) {
1547 + /* command line: "*.exe" */
1548 + strcpyW(TempApplicationName, TidyCmdLine + 1);
1549 + tmp = strchrW(TempApplicationName, L'"');
1550 + if (tmp)
1551 + *tmp = L'\0';
1552 + } else {
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'/'));
1562 + if (!tmp)
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);
1574 + else {
1575 + if(!(TempCurrentDirectory = RtlAllocateHeap(GetProcessHeap(), 0, 256))) {
1576 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1577 + return FALSE;
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);
1588 + if (!hSection)
1589 + return FALSE;
1591 + /* TODO: 16bit applications
1592 + * if (!hSection)
1593 + * ...
1594 + */
1595 + /* query section infomation */
1596 + Status = UkQuerySection(hSection, SectionImageInformation, &Sii, sizeof(Sii), NULL);
1597 + if (Status) {
1598 + NtClose(hSection);
1599 + WARN("NtQuerySection() failed(Status %x)\n", Status);
1600 + SetLastError(RtlNtStatusToDosError(Status));
1601 + return FALSE;
1604 + if (0 != (Sii.ImageCharacteristics & IMAGE_FILE_DLL)) {
1605 + NtClose(hSection);
1606 + WARN("Can't execute a DLL\n");
1607 + SetLastError(ERROR_INVALID_PARAMETER);
1608 + return FALSE;
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);
1616 + return FALSE;
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;
1644 + else
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);
1650 + return FALSE;
1652 + wine_server_send_fd(socketfd[1]);
1653 + close(socketfd[1]);
1654 + /* NtCreateProcess*/
1655 + NtCreateProcess(&hProcess,
1656 + PROCESS_ALL_ACCESS,
1657 + &ProcObjectAttributes,
1658 + NtCurrentProcess(),
1659 + bInheritHandles,
1660 + hSection,
1661 + NULL,
1662 + NULL);
1664 + NtSetInformationProcess(hProcess,
1665 + ProcessPriorityClass,
1666 + &PriorityClass,
1667 + sizeof(PROCESS_PRIORITY_CLASS));
1669 + /* TODO: send set information message */
1671 + /* creat ppb */
1672 + RtlInitUnicodeString(&RuntimeInfo_U, NULL);
1673 + if (lpStartupInfo) {
1674 + if (lpStartupInfo->lpReserved2) {
1675 + /* FIXME:
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.
1681 + */
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)))
1695 + return FALSE;
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,
1707 + hProcess,
1708 + &ppb->CurrentDirectory.Handle,
1709 + 0,
1710 + TRUE,
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),
1722 + NULL);
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;
1735 + /* wine server */
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;
1747 + } else {
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;
1773 + SERVER_END_REQ;
1775 + if(Status) {
1776 + close(socketfd[0]);
1777 + SetLastError(RtlNtStatusToDosError(Status));
1778 + return FALSE;
1781 + /* set handle, FIXME: no duplication is done */
1782 + ppb->hStdInput = hStdIn;
1783 + ppb->hStdOutput = hStdOut;
1784 + ppb->hStdError = hStdErr;
1786 + CloseHandle(process_info);
1788 + /* copy ppb */
1789 + if (lpStartupInfo) {
1790 + ppb->dwFlags = lpStartupInfo->dwFlags;
1791 + if (ppb->dwFlags & STARTF_USESHOWWINDOW)
1792 + ppb->wShowWindow = lpStartupInfo->wShowWindow;
1793 + else
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;
1800 + } else
1801 + ppb->Flags = 0;
1803 + KlInitPeb(hProcess, ppb, &ImageBaseAddress, Sii.ImageSubsystem);
1805 + RtlDestroyProcessParameters(ppb);
1807 + /* create first thread */
1808 + hThread = KlCreateFirstThread(hProcess,
1809 + lpThreadAttributes,
1810 + &Sii,
1811 + (PVOID)((ULONG_PTR)ImageBaseAddress + (ULONG)Sii.EntryPoint),
1812 + dwCreationFlags,
1813 + &lpProcessInformation->dwThreadId);
1814 + if (!hThread)
1815 + return FALSE;
1817 + /* store handle pair */
1818 + if (!store_handle_pair(hProcess, wine_phandle)) {
1819 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1820 + return FALSE;
1822 + if (!store_handle_pair(hThread, wine_thandle)) {
1823 + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1824 + return FALSE;
1827 + /* FIXME:
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.
1831 + */
1833 + /* set process and thread handles*/
1834 + lpProcessInformation->hProcess = hProcess;
1835 + lpProcessInformation->hThread = hThread;
1837 + return TRUE;
1839 +#endif
1841 /***********************************************************************
1842 * wait_input_idle
1843 @@ -3044,3 +4222,24 @@
1845 return S_OK;
1848 +#ifdef UNIFIED_KERNEL
1849 +void BaseProcessStart(unsigned long start_address, void *param)
1851 + unsigned long exit_code;
1852 + LPTHREAD_START_ROUTINE entry;
1854 + __TRY
1856 + entry = (LPTHREAD_START_ROUTINE)start_address;
1857 + exit_code = entry(param);
1859 + __EXCEPT(UnhandledExceptionFilter)
1861 + exit_code = GetExceptionCode();
1863 + __ENDTRY;
1865 + ExitProcess(exit_code);
1867 +#endif
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
1871 @@ -47,6 +47,9 @@
1872 #include "kernel_private.h"
1874 #include "wine/debug.h"
1875 +#ifdef UNIFIED_KERNEL
1876 +#include "handle.h"
1877 +#endif
1879 WINE_DEFAULT_DEBUG_CHANNEL(sync);
1881 @@ -149,6 +152,108 @@
1882 return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
1885 +#ifdef UNIFIED_KERNEL
1886 +struct mix_handle
1888 + HANDLE mixed[MAXIMUM_WAIT_OBJECTS];
1889 + int pos[MAXIMUM_WAIT_OBJECTS];
1890 + int count;
1891 + BOOLEAN wait_all;
1892 + BOOLEAN alertable;
1893 + LARGE_INTEGER * timeout;
1894 + int ret;
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;
1905 + int i;
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)
1917 + return status;
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;
1927 + } else {
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);
1934 + if (!interface) {
1935 + NtClose(h_wine.notify_event);
1936 + return status;
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]);
1959 + } else
1960 + status = h_wine.ret;
1963 + TerminateThread(interface, 0);
1964 + WaitForSingleObject(interface, INFINITE);
1965 + NtClose(interface);
1967 + NtClose(h_wine.notify_event);
1969 + return status;
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,
1977 + h_uk->mixed,
1978 + h_uk->wait_all,
1979 + h_uk->alertable,
1980 + h_uk->timeout);
1982 + SetEvent(h_uk->notify_event);
1983 + SuspendThread(GetCurrentThread());
1984 + return 0;
1986 +#endif
1988 /***********************************************************************
1989 * WaitForMultipleObjectsEx (KERNEL32.@)
1990 @@ -161,6 +266,11 @@
1991 HANDLE hloc[MAXIMUM_WAIT_OBJECTS];
1992 LARGE_INTEGER time;
1993 unsigned int i;
1994 +#ifdef UNIFIED_KERNEL
1995 + HANDLE * handle_table = hloc;
1996 + int count_wine = 0, count_u = 0;
1997 + BOOLEAN mix;
1998 +#endif
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))
2009 + count_u++;
2010 + else
2011 + count_wine++;
2013 + mix = (count_u && count_wine) ? 1 : 0;
2014 +#endif
2016 +#ifndef UNIFIED_KERNEL
2017 status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable,
2018 get_nt_timeout( &time, timeout ) );
2019 +#else
2020 + if (mix)
2021 + status = mix_wait( count, hloc, wait_all, alertable, get_nt_timeout(&time, timeout) );
2022 + else
2023 + status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable, get_nt_timeout(&time, timeout));
2024 +#endif
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
2031 @@ -41,9 +41,15 @@
2032 #include "wine/debug.h"
2034 #include "kernel_private.h"
2035 +#ifdef UNIFIED_KERNEL
2036 +#include "handle.h"
2037 +#endif
2039 WINE_DEFAULT_DEBUG_CHANNEL(thread);
2041 +#ifdef UNIFIED_KERNEL
2042 +extern int server_abort_thread( int status );
2043 +#endif
2045 /***********************************************************************
2046 * CreateThread (KERNEL32.@)
2047 @@ -57,6 +63,7 @@
2051 +#ifndef UNIFIED_KERNEL
2052 /***************************************************************************
2053 * CreateRemoteThread (KERNEL32.@)
2055 @@ -112,6 +119,148 @@
2057 return handle;
2059 +#else
2060 +#define PAGE_SIZE 0x1000
2061 +#define ROUNDUP(a, b) ((((a) + (b) - 1)/(b))*(b))
2063 +struct debug_info
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;
2089 + /* signal */
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;
2095 + __TRY
2097 + uExitCode = (lpStartAddress)((PVOID)lpParameter);
2099 + __EXCEPT(UnhandledExceptionFilter)
2101 + uExitCode = GetExceptionCode();
2103 + __ENDTRY;
2105 + ExitThread(uExitCode);
2108 +extern NTSTATUS
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);
2121 + HANDLE WINAPI
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)
2130 + HANDLE hThread;
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;
2142 + } else {
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 */
2153 + else
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,
2162 + NULL,
2163 + 0,
2164 + NULL,
2165 + NULL);
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,
2178 + &oaThreadAttribs,
2179 + dwCreationFlags & CREATE_SUSPENDED,
2180 + 0,
2181 + &nStackReserve,
2182 + &nStackCommit,
2183 + (LPTHREAD_START_ROUTINE)ThreadStartup,
2184 + &hThread,
2185 + &cidClientId,
2186 + (ULONG_PTR)lpStartAddress,
2187 + (ULONG_PTR)lpParameter);
2188 + /* failure */
2189 + if(nErrCode) {
2190 + SetLastError(nErrCode);
2191 + return NULL;
2194 + /* success */
2195 + if(lpThreadId)
2196 + *lpThreadId = (DWORD)cidClientId.UniqueThread;
2198 + return hThread;
2200 +#endif
2203 /***********************************************************************
2204 @@ -165,7 +314,11 @@
2205 if (last)
2207 LdrShutdownProcess();
2208 +#ifndef UNIFIED_KERNEL
2209 exit( code );
2210 +#else
2211 + NtTerminateProcess(GetCurrentProcess(), code);
2212 +#endif
2214 else
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) );
2223 return !status;
2224 +#else
2225 + NTSTATUS status;
2226 + BOOL self, last;
2227 + HANDLE wine_handle;
2229 + if (GetCurrentThread() != handle) {
2230 + struct handle_pair * pair = search_handle_pair(handle);
2231 + wine_handle = pair->wine_handle;
2232 + } else
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;
2243 + SERVER_END_REQ;
2245 + if (self) {
2246 + if (last) {
2247 + NtTerminateProcess(GetCurrentProcess(), exit_code);
2248 + } else {
2249 + return server_abort_thread(exit_code);
2253 + status = NtTerminateThread( handle, exit_code );
2254 + if (status) SetLastError( RtlNtStatusToDosError(status) );
2255 + return !status;
2256 +#endif
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
2263 @@ -41,6 +41,7 @@
2264 #include "winerror.h"
2265 #include "wine/exception.h"
2266 #include "wine/debug.h"
2267 +#include "handle.h"
2269 #include "kernel_private.h"
2271 @@ -48,6 +49,24 @@
2273 static unsigned int page_size;
2275 +#ifdef UNIFIED_KERNEL
2277 +NTSTATUS WINAPI
2278 +UkCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
2279 + const LARGE_INTEGER *size, ULONG protect,
2280 + ULONG sec_flags, HANDLE file );
2282 +NTSTATUS WINAPI
2283 +UkOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr );
2285 +NTSTATUS WINAPI
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 );
2290 +NTSTATUS WINAPI
2291 +UkUnmapViewOfSection( HANDLE process, PVOID addr );
2292 +#endif
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 );
2302 +#else
2303 + if ((hFile == INVALID_HANDLE_VALUE || !hFile) && attr.ObjectName)
2304 + status = UkCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
2305 + else
2306 + status = NtCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
2307 +#endif
2308 if (status == STATUS_OBJECT_NAME_EXISTS)
2309 SetLastError( ERROR_ALREADY_EXISTS );
2310 else
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 )))
2317 +#else
2318 + if ((status = UkOpenSection( &ret, access, &attr )))
2319 + if (status == STATUS_OBJECT_NAME_NOT_FOUND)
2320 + if ((status = NtOpenSection( &ret, access, &attr )))
2321 +#endif
2323 SetLastError( RtlNtStatusToDosError(status) );
2324 ret = 0;
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) );
2334 addr = NULL;
2336 +#else
2337 + if (IS_UK_HANDLE(handle))
2338 + status = UkMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
2339 + &count, ViewShare, 0, protect );
2340 + else
2341 + status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
2342 + &count, ViewShare, 0, protect );
2343 + if (status)
2345 + SetLastError( RtlNtStatusToDosError(status) );
2346 + addr = NULL;
2348 +#endif
2349 return addr;
2352 @@ -558,6 +604,9 @@
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);
2358 +#endif
2359 if (status) SetLastError( RtlNtStatusToDosError(status) );
2360 return !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
2365 @@ -8,11 +8,17 @@
2366 # plus all variables required by the global Make.rules.in
2369 +SLIBDIR = /lib
2370 +KERNELVER = `uname -r | awk -F. '{print $$1}'`
2372 DLLFLAGS = @DLLFLAGS@
2373 DLLEXT = @DLLEXT@
2374 IMPLIBEXT = @IMPLIBEXT@
2375 MINGWAR = @MINGWAR@
2376 -DEFS = -D__WINESRC__ $(EXTRADEFS)
2377 +LDRPATH =
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
2384 @@ -32,7 +38,7 @@
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
2396 @@ -33,6 +33,9 @@
2398 WINE_DEFAULT_DEBUG_CHANNEL(environ);
2400 +#ifdef UNIFIED_KERNEL
2401 +extern int get_child_socket_fd();
2402 +#endif
2403 /******************************************************************************
2404 * RtlCreateEnvironment [NTDLL.@]
2406 @@ -427,6 +430,9 @@
2407 SIZE_T size, total_size;
2408 void *ptr;
2409 NTSTATUS status;
2410 +#ifdef UNIFIED_KERNEL
2411 + int* psocketfd;
2412 +#endif
2414 RtlAcquirePebLock();
2415 cur_params = NtCurrentTeb()->Peb->ProcessParameters;
2416 @@ -454,6 +460,9 @@
2417 + Desktop->MaximumLength
2418 + ShellInfo->MaximumLength
2419 + RuntimeInfo->MaximumLength);
2420 +#ifdef UNIFIED_KERNEL
2421 + size += sizeof(int); /* expand for socket fd */
2422 +#endif
2424 total_size = size;
2425 ptr = NULL;
2426 @@ -468,7 +477,13 @@
2427 params->Environment = Environment;
2428 /* all other fields are zero */
2430 +#ifndef UNIFIED_KERNEL
2431 ptr = params + 1;
2432 +#else
2433 + psocketfd = ptr = params + 1; /* expand for socket fd */
2434 + *psocketfd = get_child_socket_fd();
2435 + ptr = (int *)ptr + 1;
2436 +#endif
2437 append_unicode_string( &ptr, CurrentDirectoryName, &params->CurrentDirectory.DosPath );
2438 append_unicode_string( &ptr, DllPath, &params->DllPath );
2439 append_unicode_string( &ptr, ImagePathName, &params->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
2443 @@ -87,6 +87,11 @@
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);
2450 +#endif
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
2461 + * UkOpenFile
2462 + * We use UkOpenFile with the system call NtOpenFile interface to do the same things,
2463 + * but NtOpenFile in wine is used.
2464 + */
2465 +NTSTATUS WINAPI UkOpenFile( PHANDLE handle, ACCESS_MASK access,
2466 + POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
2467 + ULONG sharing, ULONG options )
2469 + NTSTATUS ret;
2470 + __asm__ __volatile__ (
2471 + "movl $0x58,%%eax\n\t"
2472 + "lea 8(%%ebp),%%edx\n\t"
2473 + "int $0x2E\n\t"
2474 + :"=a" (ret)
2475 + );
2476 + return ret;
2478 +#endif
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 );
2488 +#else
2489 + io->u.Status = NtWineService(req);
2490 +#endif
2491 *handle = reply->handle;
2493 SERVER_END_REQ;
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 );
2500 +#else
2501 + io->u.Status = NtWineService(req);
2502 +#endif
2503 *handle = reply->handle;
2505 SERVER_END_REQ;
2506 @@ -352,7 +385,9 @@
2507 break;
2509 result = read(fd, &fileio->buffer[fileio->already], fileio->count - fileio->already);
2510 +#ifndef UNIFIED_KERNEL
2511 if (needs_close) close( fd );
2512 +#endif
2514 if (result < 0)
2516 @@ -454,9 +489,15 @@
2518 req->handle = handle;
2519 req->flags = 0;
2520 +#ifndef UNIFIED_KERNEL
2521 if (!(status = wine_server_call( req )) &&
2522 reply->read_timeout != TIMEOUT_INFINITE)
2523 timeouts->total = reply->read_timeout / -10000;
2524 +#else
2525 + status = NtWineService(req);
2526 + if (!status && reply->read_timeout != TIMEOUT_INFINITE)
2527 + timeouts->total = reply->read_timeout / -10000;
2528 +#endif
2530 SERVER_END_REQ;
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 );
2538 +#else
2539 + status = NtWineService(req);
2540 +#endif
2542 SERVER_END_REQ;
2544 @@ -709,7 +754,9 @@
2545 if (cvalue) NTDLL_AddCompletion( hFile, cvalue, status, total );
2547 err:
2548 +#ifndef UNIFIED_KERNEL
2549 if (needs_close) close( unix_handle );
2550 +#endif
2551 if (status == STATUS_SUCCESS)
2553 io_status->u.Status = status;
2554 @@ -793,7 +840,9 @@
2555 if (cvalue) NTDLL_AddCompletion( file, cvalue, status, total );
2557 error:
2558 +#ifndef UNIFIED_KERNEL
2559 if (needs_close) close( unix_handle );
2560 +#endif
2561 if (status == STATUS_SUCCESS)
2563 io_status->u.Status = status;
2564 @@ -834,7 +883,9 @@
2565 else
2566 result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already );
2568 +#ifndef UNIFIED_KERNEL
2569 if (needs_close) close( fd );
2570 +#endif
2572 if (result < 0)
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 );
2580 +#else
2581 + status = NtWineService(req);
2582 +#endif
2584 SERVER_END_REQ;
2586 @@ -1030,7 +1085,9 @@
2587 if (cvalue) NTDLL_AddCompletion( hFile, cvalue, status, total );
2589 err:
2590 +#ifndef UNIFIED_KERNEL
2591 if (needs_close) close( unix_handle );
2592 +#endif
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 );
2599 error:
2600 +#ifndef UNIFIED_KERNEL
2601 if (needs_close) close( unix_handle );
2602 +#endif
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 )))
2612 +#else
2613 + if (!(status = NtWineService(req)))
2614 +#endif
2615 io->Information = wine_server_reply_size( reply );
2617 SERVER_END_REQ;
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 );
2624 +#endif
2625 status = FILE_GetNtStatus();
2626 break;
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 );
2634 +#endif
2635 status = STATUS_PIPE_BROKEN;
2636 break;
2638 @@ -1394,7 +1461,9 @@
2639 if (res >= 0) io->Information += res;
2642 +#ifndef UNIFIED_KERNEL
2643 if (needs_close) close( fd );
2644 +#endif
2646 break;
2648 @@ -1672,7 +1741,11 @@
2650 req->handle = hFile;
2651 req->flags = 0;
2652 +#ifndef UNIFIED_KERNEL
2653 io->u.Status = wine_server_call( req );
2654 +#else
2655 + io->u.Status = NtWineService(req);
2656 +#endif
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 );
2666 +#endif
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 )))
2676 +#else
2677 + if (!(io->u.Status = NtWineService(req)))
2678 +#endif
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;
2684 break;
2686 +#ifndef UNIFIED_KERNEL
2687 if (needs_close) close( fd );
2688 +#endif
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 );
2698 +#endif
2700 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2701 break;
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 );
2708 +#endif
2710 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2711 break;
2712 @@ -1872,7 +1957,9 @@
2714 io->u.Status = FILE_GetNtStatus();
2716 +#ifndef UNIFIED_KERNEL
2717 if (needs_close) close( fd );
2718 +#endif
2720 else io->u.Status = STATUS_INVALID_PARAMETER_3;
2721 break;
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 );
2728 +#else
2729 + io->u.Status = NtWineService(req);
2730 +#endif
2732 SERVER_END_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 );
2740 +#else
2741 + io->u.Status = NtWineService(req);
2742 +#endif
2744 SERVER_END_REQ;
2745 } else
2746 @@ -2278,7 +2373,9 @@
2747 io->u.Status = STATUS_INVALID_PARAMETER;
2748 break;
2750 +#ifndef UNIFIED_KERNEL
2751 if (needs_close) close( fd );
2752 +#endif
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 );
2762 +#else
2763 + ret = NtWineService(req);
2764 +#endif
2765 hEvent = reply->event;
2767 SERVER_END_REQ;
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 );
2774 +#else
2775 + ret = NtWineService(req);
2776 +#endif
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 );
2786 +#else
2787 + status = NtWineService(req);
2788 +#endif
2790 SERVER_END_REQ;
2791 return status;
2792 @@ -2495,7 +2604,11 @@
2793 SERVER_START_REQ( cancel_async )
2795 req->handle = hFile;
2796 +#ifndef UNIFIED_KERNEL
2797 wine_server_call( req );
2798 +#else
2799 + NtWineService(req);
2800 +#endif
2802 SERVER_END_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 );
2810 +#else
2811 + ret = NtWineService(req);
2812 +#endif
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
2819 @@ -0,0 +1,733 @@
2821 + * init.c
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).
2828 + *
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.
2840 + */
2843 + * init.c: initiliase all that should be done before LdrInitializThunk
2844 + */
2846 +#ifdef UNIFIED_KERNEL
2847 +#include <stdio.h>
2848 +#include <stdlib.h>
2849 +#include <unistd.h>
2850 +#include <link.h>
2851 +#include <elf.h>
2852 +#include <sys/types.h>
2853 +#include <sys/stat.h>
2854 +#include <stdarg.h>
2855 +#include <dlfcn.h>
2857 +#include "ntstatus.h"
2858 +#define WIN32_NO_STATUS
2859 +#include "windef.h"
2860 +#include "winnt.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
2884 + LDR_MODULE ldr;
2885 + int nDeps;
2886 + struct _wine_modref **deps;
2887 +} WINE_MODREF;
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);
2907 +void _init(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;
2918 +size_t auxvec_len;
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)
2932 + NTSTATUS ret;
2933 + __asm__ __volatile__ (
2934 + "movl $0x15, %%eax\n\t"
2935 + "lea 8(%%ebp), %%edx\n\t"
2936 + "int $0x2E\n\t"
2937 + :"=a" (ret)
2938 + );
2939 + return ret;
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();
2952 + /*
2953 + * 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
2957 + */
2958 +__asm__ (
2959 + ".globl StartInterp\n"
2960 + "StartInterp:\n\t"
2961 + "pusha\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"
2969 + "rep movsl\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 */
2977 + "StartThunk:\n\t"
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 */
2989 + "pushl %ebp\n\t"
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 */
3002 + "popa\n\t"
3003 + "ret\n" /* return from StartInterp */
3004 + );
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)
3012 + if (Reserved) {
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";
3028 + struct stat st;
3029 + int path_len;
3031 + wine_path = malloc(MAX_PATH + sizeof(wine));
3032 + if (paths) {
3033 + paths = strdup(paths);
3034 + temp = paths;
3035 + for (p = paths; *p != 0; p++) {
3036 + while (*p != ':' && *p)
3037 + p++;
3038 + *p = 0;
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;
3048 + free(paths);
3049 + free(wine_path);
3050 + return bin_dir;
3052 + temp = p + 1;
3054 + free(paths);
3056 + free(wine_path);
3057 + return NULL;
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;
3068 + int path_len = 0;
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;
3120 + WCHAR* p;
3121 + int len = 0;
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:
3128 + * + exe path
3129 + * + system dll path:
3130 + * + .
3131 + * + 32-bit system path
3132 + * + 16-bit system path
3133 + * + windows path
3134 + * + PATH ?
3135 + */
3136 + if (!full_exe_name)
3137 + exe_path = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
3138 + else
3139 + exe_path = full_exe_name->Buffer;
3140 + if (exe_path) {
3141 + exe_path_len = (strrchrW(exe_path, '\\') - exe_path);
3142 + len += exe_path_len + 1;
3145 + len += strlenW(CurrentDirW) + 1;
3147 + get_system_paths();
3149 + if (SystemDir)
3150 + len += strlenW(SystemDir) + 1;
3152 + len += strlenW(SystemDir16) + 1;
3154 + if (WindowsDir)
3155 + len += strlenW(WindowsDir) + 1;
3157 + /* make up dll path */
3158 + if ((p = dll_path = RtlAllocateHeap(GetProcessHeap(), 0, len * sizeof(WCHAR)))) {
3159 + /* exe path */
3160 + if (exe_path) {
3161 + memcpy(dll_path, exe_path, exe_path_len * sizeof(WCHAR));
3162 + p += exe_path_len;
3163 + *p++ = ';';
3166 + /* system dll path */
3167 + strcpyW(p, CurrentDirW);
3168 + p += strlenW(p);
3169 + *p++ = ';';
3170 + if (SystemDir) {
3171 + strcpyW(p, SystemDir);
3172 + p += strlenW(p);
3173 + *p++ = ';';
3175 + strcpyW(p, SystemDir16);
3176 + p += strlenW(p);
3177 + *p++ = ';';
3178 + if (WindowsDir) {
3179 + strcpyW(p, WindowsDir);
3180 + p += strlenW(p);
3181 + *p++ = ';';
3184 + /* PATH */
3185 + dll_path[len - 1] = 0;
3186 + return dll_path;
3189 + return NULL;
3192 +/* initialize all options at startup for Unified Kernel */
3193 +void __debug_init(void)
3195 + char *wine_debug;
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) \
3206 +{ \
3207 + if ((params)) \
3208 + { \
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)); \
3217 + } \
3220 +LPSTR WINAPI GetDir(void)
3222 + static char *cmdlineA; /* ASCII command line */
3223 + ANSI_STRING ansi;
3225 + cmdlineA = (RtlUnicodeStringToAnsiString( &ansi,
3226 + &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath, TRUE) == STATUS_SUCCESS) ?
3227 + ansi.Buffer : NULL;
3229 + return cmdlineA;
3233 + * init_for_load
3234 + *
3235 + * Initializing all the parts that are done by wine-preloader
3236 + * All this initialization should be done before LdrInitializeThunk
3237 + */
3238 +void init_for_load()
3240 + WINE_MODREF *wm;
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;
3250 + int* psocketfd;
3251 + char socket_env[64];
3252 + void *addr;
3253 + SIZE_T size;
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;
3267 + size = 0x10000;
3268 + NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
3269 + user_shared_data = addr;
3271 + /* signal */
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*/
3284 + __debug_init();
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*/
3315 + if (params) {
3316 + psocketfd = (int *)(params + 1);
3317 + if (*psocketfd) {
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");
3332 + exit(1);
3335 + /* create view for main exe sections */
3336 + if (create_pe_sec_view(peb->ImageBaseAddress)) {
3337 + ERR("error in creating pe sections' views\n");
3338 + exit(1);
3341 + setenv("PWD",GetDir(),1);
3343 + /* allocate a module for main exe */
3344 + if (RtlSetCurrentDirectory_U(&params->CurrentDirectory.DosPath)) {
3345 + ERR( "error in setting current directory\n");
3346 + exit(1);
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);
3361 + if (!wm) {
3362 + ERR( "can't load %s\n", debugstr_w(fullname.Buffer));
3363 + exit(1);
3366 + /* set dll path */
3367 + dll_path = get_dll_path(&fullname);
3368 + RtlInitUnicodeString(&params->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);
3383 + SERVER_END_REQ;
3386 +__attribute__((stdcall))
3387 +int PrepareThunk(
3388 + int argc,
3389 + char **argv,
3390 + void (*init) (void),
3391 + void (*rtld_fini)(void))
3393 + char **evp, **p;
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;
3402 + while (*p++) ;
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);
3410 + free(bin_dir);
3412 + wine_init_argv0_path(wine_path);
3413 + build_dll_path();
3414 + __wine_main_argc = argc;
3415 + __wine_main_argv = argv;
3416 + __wine_main_environ = evp;
3417 + free(wine_path);
3419 + init_for_load();
3421 + /* Call the initializer of the program, if any. */
3422 + if (init)
3423 + (*init)();
3425 + /* .init in ntdll.dll.so */
3426 + _init();
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));
3435 + if (!pair)
3436 + return 0;
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)
3447 + struct list* p;
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)
3453 + return pair;
3455 + return NULL;
3458 +void delete_handle_pair(struct handle_pair* pair)
3460 + list_remove(&pair->entry);
3461 + free(pair);
3462 + handle_pairs--;
3465 +#ifdef UNIFIED_KERNEL_EXESO
3466 +int UkDebug(unsigned long arg1, unsigned long arg2, unsigned long arg3)
3468 + int ret;
3469 + __asm__ __volatile__(
3470 + "movl $234,%%eax\n\t"
3471 + "lea 8(%%ebp),%%edx\n\t"
3472 + "int $0x2E\n\t"
3473 + :"=a" (ret)
3474 + );
3475 + return ret;
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;
3486 + void *exeso;
3487 + void *image_base;
3488 + PEB *peb = NtCurrentTeb()->Peb;
3489 + IMAGE_NT_HEADERS **nt;
3490 + void *entry;
3491 + char *pipe = NULL;
3492 + int fd;
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);
3499 + if(!exeso)
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;
3506 + *nt = 0;
3508 + if (env_socket)
3509 + socket_fd = atoi(env_socket);
3511 + PrepareThunk(*pargc, argv, 0, 0);
3512 + /*
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
3516 + */
3517 + psocketfd = params + 1; /* expand for socket fd */
3518 + *psocketfd = socket_fd;
3520 + pipe = getenv("PIDTIDPIPE");
3521 + if(pipe) {
3522 + HANDLE pid, tid;
3523 + /* retrive of pid/tid should be after init_for_load() */
3524 + pid = NtCurrentTeb()->ClientId.UniqueProcess;
3525 + tid = NtCurrentTeb()->ClientId.UniqueThread;
3526 + fd = atoi(pipe);
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"
3535 + "pushl %1\n\t"
3536 + "pushl $0xdeadbeef\n\t"
3537 + "jmp *%2\n\t"
3538 + :: "r"(pargc), "r"(entry),
3539 + "r"(&ProcessStartForward)
3540 + );
3542 + exit(0);
3545 + void __attribute__((regparm(0)))
3546 +exeso_start_thunk(int unknown)
3548 + UkDebug(0, 0, 0);
3550 +#endif
3552 +#endif
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
3556 @@ -0,0 +1,182 @@
3557 +/* Script for --shared -z combreloc: shared library, combine & sort relocs */
3558 +OUTPUT_FORMAT("elf32-i386", "elf32-i386",
3559 + "elf32-i386")
3560 +OUTPUT_ARCH(i386)
3561 +ENTRY(_start)
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?
3564 + __DYNAMIC = 0; */
3565 +SECTIONS
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) }
3575 + .rel.dyn :
3577 + *(.rel.init)
3578 + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
3579 + *(.rel.fini)
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.*)
3585 + *(.rel.ctors)
3586 + *(.rel.dtors)
3587 + *(.rel.got)
3588 + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
3590 + .rela.dyn :
3592 + *(.rela.init)
3593 + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
3594 + *(.rela.fini)
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.*)
3599 + *(.rela.ctors)
3600 + *(.rela.dtors)
3601 + *(.rela.got)
3602 + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
3604 + .rel.plt : { *(.rel.plt) }
3605 + .rela.plt : { *(.rela.plt) }
3606 + .init :
3608 + KEEP (*(.init))
3609 + } =0x90909090
3610 + .plt : { *(.plt) }
3611 + .text :
3613 + *(.text .stub .text.* .gnu.linkonce.t.*)
3614 + KEEP (*(.text.*personality*))
3615 + /* .gnu.warning sections are handled specially by elf32.em. */
3616 + *(.gnu.warning)
3617 + } =0x90909090
3618 + .fini :
3620 + KEEP (*(.fini))
3621 + } =0x90909090
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)) }
3647 + .ctors :
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
3657 + is in. */
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.*)))
3665 + KEEP (*(.ctors))
3667 + .dtors :
3669 + KEEP (*crtbegin*.o(.dtors))
3670 + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
3671 + KEEP (*(SORT(.dtors.*)))
3672 + KEEP (*(.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) }
3680 + .data :
3682 + *(.data .data.* .gnu.linkonce.d.*)
3683 + KEEP (*(.gnu.linkonce.d.*personality*))
3684 + SORT(CONSTRUCTORS)
3686 + .data1 : { *(.data1) }
3687 + _edata = .;
3688 + PROVIDE (edata = .);
3689 + __bss_start = .;
3690 + .bss :
3692 + *(.dynbss)
3693 + *(.bss .bss.* .gnu.linkonce.b.*)
3694 + *(COMMON)
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);
3701 + _end = .;
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. */
3715 + /* DWARF 1 */
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) }
3724 + /* DWARF 2 */
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
3742 @@ -52,6 +52,15 @@
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);
3754 +#endif
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 )
3764 +#else
3765 +WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
3766 +#endif
3768 WINE_MODREF *wm;
3769 const WCHAR *p;
3770 @@ -1333,10 +1346,21 @@
3771 builtin_load_info->status = STATUS_INVALID_IMAGE_FORMAT;
3772 return;
3774 +#ifndef UNIFIED_KERNEL
3775 addr = module;
3776 size = nt->OptionalHeader.SizeOfImage;
3777 NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
3778 MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
3779 +#else
3780 + if (is_ntdll)
3781 + is_ntdll = 0;
3782 + else {
3783 + addr = module;
3784 + size = nt->OptionalHeader.SizeOfImage;
3785 + NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
3786 + MEM_SYSTEM | MEM_IMAGE, PAGE_EXECUTE_WRITECOPY );
3787 + }
3788 +#endif
3789 /* create the MODREF */
3791 if (!(fullname = get_builtin_fullname( builtin_load_info->filename, filename )))
3792 @@ -2350,6 +2374,67 @@
3793 return ret;
3796 +#ifdef UNIFIED_KERNEL
3798 + * get loaded dll's handle
3799 + */
3800 +void *get_dll_handle(char *dll_name)
3802 + WCHAR module_name[32];
3803 + PLIST_ENTRY mark, entry;
3804 + PLDR_MODULE mod;
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;
3822 + return NULL;
3823 + } else {
3824 + WCHAR *ptr = RtlAllocateHeap(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
3825 + if (!ptr) return NULL;
3826 + ascii_to_unicode(ptr, dll_name, len);
3827 + ptr[len] = 0;
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 );
3841 + return NULL;
3846 + * find symbol in loaded builtin dll
3847 + */
3848 +void *find_builtin_symbol(const char *dll_name, const char *symbol)
3850 + void *dll_handle = get_dll_handle((char *)dll_name);
3851 + char error[1024];
3852 + int err_size = sizeof(error);
3854 + return wine_dlsym(dll_handle, symbol, error, err_size);
3856 +#endif
3858 /***********************************************************************
3859 * attach_process_dlls
3860 @@ -2360,7 +2445,11 @@
3862 NTSTATUS status;
3864 +#ifndef UNIFIED_KERNEL
3865 pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
3866 +#else
3867 + sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
3868 +#endif
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;
3879 +#endif
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;
3889 +#endif
3890 if ((status = server_init_process_done()) != STATUS_SUCCESS) goto error;
3892 +#ifndef UNIFIED_KERNEL
3893 actctx_init();
3894 +#endif
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")))
3900 + goto error;
3902 + if (!(process_init = find_builtin_symbol("kernel32.dll", "process_init")))
3903 + goto error;
3905 + if (!(ThreadStartup = find_builtin_symbol("kernel32.dll", "ThreadStartup")))
3906 + goto error;
3908 + if (!(unhandled_exception_filter = find_builtin_symbol("kernel32.dll", "UnhandledExceptionFilter")))
3909 + goto error;
3912 + process_init();
3913 + actctx_init();
3914 +#endif
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 );
3920 +#endif
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 );
3929 +#endif
3931 if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
3932 return;
3933 @@ -2560,6 +2680,10 @@
3935 PLIST_ENTRY mark, entry;
3936 LPWSTR buffer, p;
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'};
3940 +#endif
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))
3952 + continue;
3953 +#endif
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
3960 @@ -5,7 +5,7 @@
3961 VPATH = @srcdir@
3962 MODULE = ntdll.dll
3963 IMPORTLIB = ntdll
3964 -EXTRALIBS = @IOKITLIB@
3965 +EXTRALIBS = @IOKITLIB@-ldl -lpthread
3966 EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000
3968 C_SRCS = \
3969 @@ -51,13 +51,15 @@
3970 time.c \
3971 version.c \
3972 virtual.c \
3973 - wcstring.c
3974 + wcstring.c \
3975 + init.c
3977 RC_SRCS = version.rc
3979 EXTRA_OBJS = relay32.o
3981 @MAKE_DLL_RULES@
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
3989 @@ -36,6 +36,9 @@
3990 #include "winternl.h"
3991 #include "ntdll_misc.h"
3992 #include "wine/server.h"
3993 +#ifdef UNIFIED_KERNEL
3994 +#include "handle.h"
3995 +#endif
3997 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
3999 @@ -98,6 +101,7 @@
4001 NTSTATUS ret;
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;
4010 SERVER_END_REQ;
4011 +#else
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;
4021 + else
4022 + req->handle = NULL;
4023 + } else
4024 + req->handle = ProcessHandle;
4025 + req->access = DesiredAccess;
4026 + req->attributes = 0;
4027 + req->flags = 0;
4028 + ret = wine_server_call( req );
4029 + if (!ret) *TokenHandle = reply->token;
4031 + SERVER_END_REQ;
4032 +#endif
4034 return ret;
4036 @@ -126,6 +152,7 @@
4038 NTSTATUS ret;
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;
4047 SERVER_END_REQ;
4048 +#else
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;
4060 + else
4061 + req->handle = NULL;
4063 + else
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;
4072 + SERVER_END_REQ;
4073 +#endif
4075 return ret;
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
4080 @@ -67,10 +67,17 @@
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 );
4089 +#else
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 );
4094 +#endif
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
4101 @@ -134,7 +134,7 @@
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
4118 +# Thread
4119 +@ cdecl RtlRosCreateUserThread(long ptr long long ptr ptr ptr ptr ptr long long)
4121 +# Attributes
4122 +@ cdecl RtlRosR32AttribsToNativeAttribs(ptr ptr)
4124 +# Process
4125 +@ stdcall NtCreateProcess(long long ptr long long long long long)
4127 +# Section
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
4146 @@ -38,6 +38,9 @@
4147 #include "winternl.h"
4148 #include "ntdll_misc.h"
4149 #include "wine/server.h"
4150 +#ifdef UNIFIED_KERNEL
4151 +#include "handle.h"
4152 +#endif
4154 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
4156 @@ -59,6 +62,7 @@
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;
4163 switch (info_class)
4164 @@ -112,6 +116,73 @@
4165 status = STATUS_NOT_IMPLEMENTED;
4166 break;
4168 +#else
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);
4194 + SERVER_END_REQ;
4196 + break;
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;
4206 + req->flags = 0;
4207 + req->mask = 0;
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);
4216 + SERVER_END_REQ;
4218 + break;
4219 + default:
4220 + FIXME("Unsupported information class %u\n", info_class);
4221 + status = STATUS_NOT_IMPLEMENTED;
4222 + break;
4225 + else
4227 + __asm__ __volatile__ (
4228 + "movl $0x86,%%eax\n\t"
4229 + "lea 8(%%ebp),%%edx\n\t"
4230 + "int $0x2E\n\t"
4231 + :"=a" (status)
4232 + );
4234 +#endif
4235 return status;
4238 @@ -129,6 +200,7 @@
4239 TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
4240 handle, info_class, ptr, len);
4242 +#ifndef UNIFIED_KERNEL
4243 switch (info_class)
4245 case ObjectDataInformation:
4246 @@ -154,6 +226,45 @@
4247 status = STATUS_NOT_IMPLEMENTED;
4248 break;
4250 +#else
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;
4264 + req->flags = 0;
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 );
4270 + SERVER_END_REQ;
4272 + break;
4273 + default:
4274 + FIXME("Unsupported information class %u\n", info_class);
4275 + status = STATUS_NOT_IMPLEMENTED;
4276 + break;
4279 + else
4281 + __asm__ __volatile__ (
4282 + "movl $0xB9,%%eax\n\t"
4283 + "lea 8(%%ebp),%%edx\n\t"
4284 + "int $0x2E\n\t"
4285 + :"=a" (status)
4286 + );
4288 +#endif
4289 return status;
4292 @@ -252,6 +363,7 @@
4293 ACCESS_MASK access, ULONG attributes, ULONG options )
4295 NTSTATUS ret;
4296 +#ifndef UNIFIED_KERNEL
4297 SERVER_START_REQ( dup_handle )
4299 req->src_process = source_process;
4300 @@ -277,6 +389,45 @@
4303 SERVER_END_REQ;
4304 +#else
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)
4321 + if (reply->self)
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 );
4331 + SERVER_END_REQ;
4333 + else
4335 + __asm__ __volatile__ (
4336 + "movl $0x34,%%eax\n\t"
4337 + "lea 8(%%ebp),%%edx\n\t"
4338 + "int $0x2E\n\t"
4339 + :"=a" (ret)
4340 + );
4342 +#endif
4343 return ret;
4346 @@ -297,6 +448,7 @@
4347 NTSTATUS ret;
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 @@
4356 SERVER_END_REQ;
4357 if (fd != -1) close( fd );
4358 +#else
4359 + if (!IS_UK_HANDLE(Handle))
4361 + /* wine handle */
4362 + SERVER_START_REQ( close_handle )
4364 + req->handle = Handle;
4365 + ret = wine_server_call( req );
4367 + SERVER_END_REQ;
4368 + if (fd != -1) close( fd );
4370 + else
4372 + __asm__ __volatile__ (
4373 + "movl $0x11,%%eax\n\t"
4374 + "lea 8(%%ebp),%%edx\n\t"
4375 + "int $0x2E\n\t"
4376 + :"=a" (ret)
4377 + );
4378 + if (!ret)
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 );
4390 + SERVER_END_REQ;
4391 + if (fd != -1) close( fd );
4392 + delete_handle_pair(pair);
4396 +#endif
4397 return ret;
4400 @@ -424,6 +615,7 @@
4402 NTSTATUS ret;
4404 +#ifndef UNIFIED_KERNEL
4405 if (restart) *context = 0;
4407 if (single_entry)
4408 @@ -460,6 +652,52 @@
4409 FIXME("multiple entries not implemented\n");
4410 ret = STATUS_NOT_IMPLEMENTED;
4412 +#else
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;
4438 + (*context)++;
4441 + SERVER_END_REQ;
4442 + if (ret_size)
4443 + *ret_size = buffer->ObjectName.MaximumLength + buffer->ObjectTypeName.MaximumLength + sizeof(*buffer);
4444 + } else {
4445 + FIXME("multiple entries not implemented\n");
4446 + ret = STATUS_NOT_IMPLEMENTED;
4448 + } else {
4449 + __asm__ __volatile__ (
4450 + "movl $0x76,%%eax\n\t"
4451 + "lea 8(%%ebp),%%edx\n\t"
4452 + "int $0x2E\n\t"
4453 + :"=a" (ret)
4454 + );
4457 +#endif
4459 return ret;
4461 @@ -587,6 +825,7 @@
4462 NTSTATUS ret;
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 @@
4472 SERVER_END_REQ;
4473 +#else
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;
4488 + SERVER_END_REQ;
4490 + else
4492 + __asm__ __volatile__ (
4493 + "movl $0x8C,%%eax\n\t"
4494 + "lea 8(%%ebp),%%edx\n\t"
4495 + "int $0x2E\n\t"
4496 + :"=a" (ret)
4497 + );
4499 +#endif
4500 return ret;
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 @@
4507 size -= 4;
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)
4520 + nts = !nts;
4521 + goto out;
4524 +#endif
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
4531 @@ -34,12 +34,42 @@
4532 #include "winternl.h"
4533 #include "ntdll_misc.h"
4534 #include "wine/server.h"
4535 +#ifdef UNIFIED_KERNEL
4536 +#include "handle.h"
4537 +#endif
4539 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
4542 * Process object
4544 +#ifdef UNIFIED_KERNEL
4546 +NTSTATUS WINAPI
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)
4556 + NTSTATUS ret;
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"
4565 + "int $0x2E\n\t"
4566 + :"=a" (ret)
4567 + );
4568 + return ret;
4570 +#endif
4572 /******************************************************************************
4573 * NtTerminateProcess [NTDLL.@]
4574 @@ -49,6 +79,7 @@
4575 NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
4577 NTSTATUS ret;
4578 +#ifndef UNIFIED_KERNEL
4579 BOOL self;
4580 SERVER_START_REQ( terminate_process )
4582 @@ -59,6 +90,33 @@
4584 SERVER_END_REQ;
4585 if (self) exit( exit_code );
4586 +#else
4587 + BOOL self;
4588 + HANDLE wine_handle;
4590 + if (GetCurrentProcess() != handle) {
4591 + struct handle_pair * pair = search_handle_pair(handle);
4592 + wine_handle = pair->wine_handle;
4593 + } else
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;
4603 + SERVER_END_REQ;
4605 + /* no return, if handle == 0xffffffff */
4606 + __asm__ __volatile__ (
4607 + "movl $0xD3,%%eax\n\t"
4608 + "lea 8(%%ebp),%%edx\n\t"
4609 + "int $0x2E\n\t"
4610 + :"=a" (ret)
4611 + );
4612 +#endif
4613 return ret;
4616 @@ -108,6 +166,7 @@
4617 OUT PULONG ReturnLength)
4619 NTSTATUS ret = STATUS_SUCCESS;
4620 +#ifndef UNIFIED_KERNEL
4621 ULONG len = 0;
4623 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
4624 @@ -340,6 +399,14 @@
4627 if (ReturnLength) *ReturnLength = len;
4628 +#else
4629 + __asm__ __volatile__ (
4630 + "movl $0x7D,%%eax\n\t"
4631 + "lea 8(%%ebp),%%edx\n\t"
4632 + "int $0x2E\n\t"
4633 + :"=a" (ret)
4634 + );
4635 +#endif
4637 return ret;
4639 @@ -356,6 +423,7 @@
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;
4649 break;
4651 +#else
4652 + __asm__ __volatile__ (
4653 + "movl $0xBA,%%eax\n\t"
4654 + "lea 8(%%ebp),%%edx\n\t"
4655 + "int $0x2E\n\t"
4656 + :"=a" (ret)
4657 + );
4658 +#endif
4659 return ret;
4662 @@ -425,6 +501,7 @@
4664 NTSTATUS status;
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;
4673 SERVER_END_REQ;
4674 +#else
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"
4681 + "int $0x2E\n\t"
4682 + :"=a" (status)
4683 + );
4685 + if (!status)
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 );
4693 + if (!status)
4695 + wine_handle = reply->handle;
4696 + if (!store_handle_pair(*uk_handle, wine_handle))
4697 + return STATUS_NO_MEMORY;
4700 + SERVER_END_REQ;
4702 +#endif
4703 return status;
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
4708 @@ -45,6 +45,11 @@
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);
4715 +#endif
4717 /******************************************************************************
4718 * NtCreateKey [NTDLL.@]
4719 * ZwCreateKey [NTDLL.@]
4720 @@ -72,7 +77,11 @@
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 )))
4726 +#else
4727 + if (!(ret = NtWineService(&__req)))
4728 +#endif
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 );
4738 +#else
4739 + ret = NtWineService( req );
4740 +#endif
4741 *retkey = reply->hkey;
4743 SERVER_END_REQ;
4744 @@ -162,7 +175,11 @@
4745 SERVER_START_REQ( delete_key )
4747 req->hkey = hkey;
4748 +#ifndef UNIFIED_KERNEL
4749 ret = wine_server_call( req );
4750 +#else
4751 + ret = NtWineService( req );
4752 +#endif
4754 SERVER_END_REQ;
4755 return ret;
4756 @@ -193,7 +210,11 @@
4758 req->hkey = hkey;
4759 wine_server_add_data( req, name->Buffer, name->Length );
4760 +#ifndef UNIFIED_KERNEL
4761 ret = wine_server_call( req );
4762 +#else
4763 + ret = NtWineService( req );
4764 +#endif
4766 SERVER_END_REQ;
4767 return ret;
4768 @@ -230,7 +251,11 @@
4769 req->index = index;
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 )))
4774 +#else
4775 + if (!(ret = NtWineService( req )))
4776 +#endif
4778 LARGE_INTEGER modif;
4780 @@ -445,7 +470,11 @@
4781 req->index = index;
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 )))
4786 +#else
4787 + if (!(ret = NtWineService( req )))
4788 +#endif
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 @@
4793 req->hkey = handle;
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 )))
4798 +#else
4799 + if (!(ret = NtWineService( req )))
4800 +#endif
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 )
4807 req->hkey = key;
4808 +#ifndef UNIFIED_KERNEL
4809 ret = wine_server_call( req );
4810 +#else
4811 + ret = NtWineService( req );
4812 +#endif
4814 SERVER_END_REQ;
4816 @@ -607,7 +644,11 @@
4817 req->hkey = attr->RootDirectory;
4818 req->file = hive;
4819 wine_server_add_data(req, attr->ObjectName->Buffer, attr->ObjectName->Length);
4820 +#ifndef UNIFIED_KERNEL
4821 ret = wine_server_call( req );
4822 +#else
4823 + ret = NtWineService( req );
4824 +#endif
4826 SERVER_END_REQ;
4828 @@ -656,7 +697,11 @@
4829 req->event = Event;
4830 req->subtree = WatchSubtree;
4831 req->filter = CompletionFilter;
4832 +#ifndef UNIFIED_KERNEL
4833 ret = wine_server_call( req );
4834 +#else
4835 + ret = NtWineService( req );
4836 +#endif
4838 SERVER_END_REQ;
4840 @@ -730,7 +775,11 @@
4842 req->hkey = KeyHandle;
4843 req->file = FileHandle;
4844 +#ifndef UNIFIED_KERNEL
4845 ret = wine_server_call( req );
4846 +#else
4847 + ret = NtWineService( req );
4848 +#endif
4850 SERVER_END_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 );
4858 +#else
4859 + ret = NtWineService( req );
4860 +#endif
4862 SERVER_END_REQ;
4863 return ret;
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);
4870 +#else
4871 + ret = NtWineService( req );
4872 +#endif
4874 SERVER_END_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
4879 @@ -60,6 +60,8 @@
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));
4890 #endif
4892 +#ifdef UNIFIED_KERNEL
4893 +NTSTATUS WINAPI
4894 +NtWineService(struct __server_request_info * ReqMsg)
4896 + NTSTATUS ret;
4898 + __asm__ __volatile__ (
4899 + "movl $0xe8,%%eax\n\t"
4900 + "lea 8(%%ebp),%%edx\n\t"
4901 + "int $0x2E\n\t"
4902 + :"=a" (ret)
4903 + );
4905 + return ret;
4908 +#endif
4909 /* die on a fatal error; use only during initialization */
4910 static void fatal_error( const char *err, ... )
4912 @@ -139,6 +158,7 @@
4914 void server_exit_thread( int status )
4916 +#ifndef UNIFIED_KERNEL
4917 struct wine_pthread_thread_info info;
4918 SIZE_T size;
4919 int fds[4];
4920 @@ -173,20 +193,57 @@
4921 close( fds[2] );
4922 close( fds[3] );
4923 pthread_functions.exit_thread( &info );
4924 +#else
4925 + int fds[4];
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;
4939 + close( fds[0] );
4940 + close( fds[1] );
4941 + close( fds[2] );
4942 + close( fds[3] );
4944 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4946 + NtTerminateThread(GetCurrentThread(),0);
4947 +#endif
4951 /***********************************************************************
4952 * server_abort_thread
4954 +#ifndef UNIFIED_KERNEL
4955 void server_abort_thread( int status )
4956 +#else
4957 +int server_abort_thread( int status )
4958 +#endif
4960 +#ifndef UNIFIED_KERNEL
4961 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4962 +#else
4963 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
4964 +#endif
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 );
4971 +#else
4973 + return NtTerminateThread(GetCurrentThread(), status);
4974 +#endif
4978 @@ -323,10 +380,18 @@
4979 sigset_t old_set;
4980 unsigned int ret;
4982 +#ifndef UNIFIED_KERNEL
4983 pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, &old_set );
4984 +#else
4985 + sigprocmask( SIG_BLOCK, &server_block_set, &old_set );
4986 +#endif
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 );
4991 +#else
4992 + sigprocmask( SIG_SETMASK, &old_set, NULL );
4993 +#endif
4994 return ret;
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 );
5003 +#else
5004 + sigprocmask( SIG_BLOCK, &server_block_set, sigset );
5005 +#endif
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 );
5015 +#else
5016 + sigprocmask( SIG_SETMASK, sigset, NULL );
5017 +#endif
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);
5027 +#else
5028 + return server_abort_thread(0);
5029 +#endif
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
5039 +#else
5040 #define FD_CACHE_ENTRIES 128
5041 +#endif
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;
5053 + else
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;
5061 +#else
5062 unsigned long idx = ((unsigned long)handle >> 2) - 1;
5063 *entry = idx / FD_CACHE_BLOCK_SIZE;
5064 return idx % FD_CACHE_BLOCK_SIZE;
5065 +#endif
5069 @@ -585,6 +681,7 @@
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 @@
5080 SERVER_END_REQ;
5081 +#else
5082 + SERVER_START_REQ( get_handle_fd )
5084 + req->handle = handle;
5085 + if (!IS_UK_HANDLE(handle))
5086 + ret = wine_server_call( req );
5087 + else
5088 + ret = NtWineService( req );
5090 + if (!ret)
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 );
5097 + else
5098 + fd = reply->fd;
5100 + if (fd != -1)
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 ));
5107 + } else {
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;
5115 + SERVER_END_REQ;
5116 +#endif
5118 done:
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 );
5126 +#else
5127 + sigprocmask( SIG_BLOCK, &server_block_set, NULL );
5128 +#endif
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;
5139 +#endif
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
5146 @@ -57,6 +57,9 @@
5147 #include "wine/server.h"
5148 #include "wine/debug.h"
5149 #include "ntdll_misc.h"
5150 +#ifdef UNIFIED_KERNEL
5151 +#include "handle.h"
5152 +#endif
5154 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
5156 @@ -143,6 +146,7 @@
5157 IN LONG InitialCount,
5158 IN LONG MaximumCount )
5160 +#ifndef UNIFIED_KERNEL
5161 DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0;
5162 NTSTATUS ret;
5163 struct object_attributes objattr;
5164 @@ -176,6 +180,16 @@
5165 SERVER_END_REQ;
5167 NTDLL_free_struct_sd( sd );
5168 +#else
5169 + NTSTATUS ret;
5171 + __asm__ __volatile__ (
5172 + "movl $0x25,%%eax\n\t"
5173 + "lea 8(%%ebp),%%edx\n\t"
5174 + "int $0x2E\n\t"
5175 + :"=a" (ret)
5176 + );
5177 +#endif
5179 return ret;
5181 @@ -187,6 +201,7 @@
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;
5187 NTSTATUS ret;
5189 @@ -202,6 +217,16 @@
5190 *SemaphoreHandle = reply->handle;
5192 SERVER_END_REQ;
5193 +#else
5194 + NTSTATUS ret;
5196 + __asm__ __volatile__ (
5197 + "movl $0x62,%%eax\n\t"
5198 + "lea 8(%%ebp),%%edx\n\t"
5199 + "int $0x2E\n\t"
5200 + :"=a" (ret)
5201 + );
5202 +#endif
5203 return ret;
5206 @@ -226,6 +251,7 @@
5207 NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous )
5209 NTSTATUS ret;
5210 +#ifndef UNIFIED_KERNEL
5211 SERVER_START_REQ( release_semaphore )
5213 req->handle = handle;
5214 @@ -236,6 +262,14 @@
5217 SERVER_END_REQ;
5218 +#else
5219 + __asm__ __volatile__ (
5220 + "movl $0x9E,%%eax\n\t"
5221 + "lea 8(%%ebp),%%edx\n\t"
5222 + "int $0x2E\n\t"
5223 + :"=a" (ret)
5224 + );
5225 +#endif
5226 return ret;
5229 @@ -419,6 +453,7 @@
5230 IN BOOLEAN InitialOwner)
5232 NTSTATUS status;
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 @@
5238 SERVER_END_REQ;
5240 NTDLL_free_struct_sd( sd );
5241 +#else
5242 + __asm__ __volatile__ (
5243 + "movl $0x1E,%%eax\n\t"
5244 + "lea 8(%%ebp),%%edx\n\t"
5245 + "int $0x2E\n\t"
5246 + :"=a" (status)
5247 + );
5248 +#endif
5250 return status;
5252 @@ -461,6 +504,7 @@
5253 IN const OBJECT_ATTRIBUTES* attr )
5255 NTSTATUS status;
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;
5263 SERVER_END_REQ;
5264 +#else
5265 + __asm__ __volatile__ (
5266 + "movl $0x5C,%%eax\n\t"
5267 + "lea 8(%%ebp),%%edx\n\t"
5268 + "int $0x2E\n\t"
5269 + :"=a" (status)
5270 + );
5271 +#endif
5272 return status;
5275 @@ -486,6 +538,7 @@
5277 NTSTATUS status;
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;
5286 SERVER_END_REQ;
5287 +#else
5288 + __asm__ __volatile__ (
5289 + "movl $0x9D,%%eax\n\t"
5290 + "lea 8(%%ebp),%%edx\n\t"
5291 + "int $0x2E\n\t"
5292 + :"=a" (status)
5293 + );
5294 +#endif
5295 return status;
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);
5304 +#else
5305 + return server_abort_thread(0);
5306 +#endif
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 );
5322 +#else
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);
5335 + else {
5336 + do{
5337 + __asm__ __volatile__ (
5338 + "movl $0xDE,%%eax\n\t"
5339 + "lea 8(%%ebp),%%edx\n\t"
5340 + "int $0x2E\n\t"
5341 + :"=a" (ret)
5342 + );
5343 + } while (-EINTR == ret);
5346 + return ret;
5347 +#endif
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
5354 @@ -42,6 +42,193 @@
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"
5361 +#include <stdio.h>
5362 +#include <elf.h>
5363 +#include <link.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;
5375 +typedef struct
5377 + void *tcb; /* Pointer to the TCB. Not necessarily the
5378 + thread descriptor used by libpthread. */
5379 + /* dtv_t *dtv; */
5380 + void *dtv;
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;
5386 +} tcbhead_t;
5388 +typedef struct list_head
5390 + struct list_head *next;
5391 + struct list_head *prev;
5392 +} list_t;
5394 +typedef int lll_lock_t;
5395 +typedef unsigned long long int hp_timing_t;
5397 +struct robust_list_head
5399 + void *list;
5400 + long int futex_offset;
5401 + void *list_op_pending;
5404 +/* Thread descriptor data structure. */
5405 +struct pthread
5407 + union
5409 + /* This overlaps the TCB as used for TLS without threads (see tls.h). */
5410 + tcbhead_t header;
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];
5416 + };
5418 + /* This descriptor's link on the `stack_used' or `__stack_user' list. */
5419 + list_t list;
5421 + /* Thread ID - which is also a 'is this thread descriptor (and
5422 + therefore stack) used' flag. */
5423 + pid_t tid;
5425 + /* Process ID - thread group ID in kernel speak. */
5426 + pid_t pid;
5428 + /* List of robust mutexes the thread is holding. */
5429 +/* union
5431 + __pthread_slist_t robust_list; */
5432 + struct robust_list_head robust_head;
5433 +/* }; */
5435 + /* List of cleanup buffers. */
5436 + /* struct _pthread_cleanup_buffer *cleanup; */
5437 + void *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. */
5447 + int flags;
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
5455 + wrapping, too. */
5456 + uintptr_t seq;
5458 + /* Data pointer. */
5459 + void *data;
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. */
5472 + bool user_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. */
5482 + lll_lock_t lock;
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
5491 + stored here.
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. */
5499 + void *result;
5501 + /* Scheduling parameters for the new thread. */
5502 + struct sched_param schedparam;
5503 + int schedpolicy;
5505 + /* Start position of the code to be executed and the argument passed
5506 + to the function. */
5507 + void *(*start_routine) (void *);
5508 + void *arg;
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; */
5519 + char exc[32];
5521 + /* If nonzero pointer to area allocated for the stack and its
5522 + size. */
5523 + void *stackblock;
5524 + size_t stackblock_size;
5525 + /* Size of the included guard area. */
5526 + size_t guardsize;
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; */
5532 + void *tpp;
5534 + /* Resolver state. */
5535 + /* struct __res_state res; */
5536 + char res[0x200];
5537 +} __attribute ((aligned(16)));
5539 +static inline void set_pthread_tid(struct pthread *pthread, pid_t tid)
5541 + pthread->tid = tid;
5544 +#endif
5546 WINE_DEFAULT_DEBUG_CHANNEL(thread);
5547 WINE_DECLARE_DEBUG_CHANNEL(relay);
5548 @@ -64,7 +251,25 @@
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;
5554 +#else
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);
5570 +#endif
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 )
5580 +#else
5581 +NTSTATUS init_user_process_params( SIZE_T info_size, HANDLE *exe_file )
5582 +#endif
5584 void *ptr;
5585 SIZE_T env_size;
5586 @@ -405,6 +614,7 @@
5590 +#ifndef UNIFIED_KERNEL
5591 /***********************************************************************
5592 * start_thread
5594 @@ -451,6 +661,50 @@
5595 else
5596 call_thread_func( func, arg );
5598 +#else
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));
5616 + SIGNAL_Init();
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)
5626 + __TRY
5628 + MODULE_DllThreadAttach( NULL );
5630 + __EXCEPT(unhandled_exception_filter)
5632 + NtTerminateThread( GetCurrentThread(), GetExceptionCode() );
5634 + __ENDTRY
5636 + else
5637 + MODULE_DllThreadAttach( NULL );
5639 + return;
5641 +#endif
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;
5651 +#else
5652 + info->pthread_info.entry = (void *)start_thread;
5653 +#endif
5654 info->entry_point = start;
5655 info->entry_arg = param;
5657 @@ -598,6 +856,601 @@
5658 return status;
5661 +#ifdef UNIFIED_KERNEL
5662 +NTSTATUS WINAPI
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)
5672 + NTSTATUS ret;
5673 + __asm__ __volatile__ (
5674 + "movl $0x27,%%eax\n\t"
5675 + "lea 8(%%ebp),%%edx\n\t"
5676 + "int $0x2E\n\t"
5677 + :"=a" (ret)
5678 + );
5679 + return ret;
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;
5696 + } else
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;
5715 + /* valid 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;
5727 + /* valid stack */
5728 + return STATUS_SUCCESS;
5732 +NTSTATUS NTAPI
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;
5742 + SIZE_T nDummy;
5743 + NTSTATUS nErrCode;
5744 + PVOID pStackBase;
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);
5752 + /* failure */
5753 + if(nErrCode)
5754 + return nErrCode;
5756 + /* validate the stack */
5757 + nErrCode = RtlpRosValidateLinearUserStack(pStackBase, pStackLimit, FALSE);
5759 + /* failure */
5760 + if(nErrCode)
5761 + return nErrCode;
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;
5774 + else
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),
5792 + &nDummy);
5794 + /* failure */
5795 + if(nErrCode)
5796 + return nErrCode;
5798 + /* write the parameter */
5799 + nErrCode = NtWriteVirtualMemory(ProcessHandle,
5800 + ((PUCHAR)pStackBase) - 2 * sizeof(ULONG_PTR),
5801 + (void *)&StartAddress,
5802 + sizeof(StartAddress),
5803 + &nDummy);
5805 + /* failure */
5806 + if(nErrCode)
5807 + return nErrCode;
5809 + /* write the return address */
5810 + return NtWriteVirtualMemory(ProcessHandle,
5811 + ((PUCHAR)pStackBase) - ReserveSize,
5812 + &spRetAddr,
5813 + sizeof(spRetAddr),
5814 + &nDummy);
5817 +NTSTATUS NTAPI RtlRosDeleteStack(IN HANDLE ProcessHandle,
5818 + IN PINITIAL_TEB InitialTeb)
5820 + PVOID pStackLowest = NULL;
5821 + ULONG_PTR nSize;
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 */
5829 + if(pStackLowest)
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,
5854 + StackZeroBits,
5855 + (SIZE_T *)&StackSize,
5856 + MEM_RESERVE | MEM_COMMIT,
5857 + PAGE_READWRITE);
5858 + /* failure */
5859 + if (nErrCode)
5860 + goto l_Fail;
5862 + InitialTeb->StackLimit = InitialTeb->StackBase;
5863 + InitialTeb->StackBase = (PVOID)((unsigned long)InitialTeb->StackBase + StackSize);
5865 + /* success */
5866 + return STATUS_SUCCESS;
5868 + /* deallocate the stack */
5869 + RtlRosDeleteStack(ProcessHandle, InitialTeb);
5871 + /* failure */
5872 +l_Fail:
5873 + assert(nErrCode);
5874 + return nErrCode;
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;
5884 + int i = 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;
5892 + PVOID cmd_addr;
5893 + PWCHAR cmd_line_w = NULL, wc;
5894 + PWCHAR app_name_w = NULL;
5895 + PEB child_peb;
5896 + RTL_USER_PROCESS_PARAMETERS child_ppb;
5897 + NTSTATUS ret;
5899 + ret = NtReadVirtualMemory(ProcessHandle,
5900 + (PVOID)0x7ffdf000UL,
5901 + (PVOID)&child_peb,
5902 + sizeof(PEB),
5903 + &size);
5904 + if (ret)
5905 + return ret;
5907 + ret = NtReadVirtualMemory(ProcessHandle,
5908 + (PVOID)child_peb.ProcessParameters,
5909 + (PVOID)&child_ppb,
5910 + sizeof(RTL_USER_PROCESS_PARAMETERS),
5911 + &size);
5912 + if (ret)
5913 + return ret;
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,
5923 + cmd_addr,
5924 + (PVOID)cmd_line_w,
5925 + child_ppb.CommandLine.MaximumLength,
5926 + &size);
5927 + if (ret)
5928 + goto out;
5930 + size /= sizeof(WCHAR);
5931 + c = cmd_line = (char *)malloc(size + 256);
5932 + for (wc = cmd_line_w; wc < cmd_line_w + size; wc++) {
5933 +#if 1
5934 + if (in_app_name > 1) {
5935 + *c++ = (unsigned char)*wc;
5937 + if (*wc == (WCHAR)'"') {
5938 + if (!in_app_name)
5939 + app_name_w = wc + 1;
5940 + else {
5941 + UNICODE_STRING nt_name;
5942 + ANSI_STRING unix_name = {0, 0, NULL};
5944 + /* change NT file name to Linux name */
5945 + *wc++ = (WCHAR)0;
5946 + if (!RtlDosPathNameToNtPathName_U(app_name_w, &nt_name, NULL, NULL))
5947 + goto out;
5948 + if (wine_nt_to_unix_file_name(&nt_name, &unix_name, FILE_OPEN, FALSE)) {
5949 + RtlFreeUnicodeString(&nt_name);
5950 + goto out;
5952 + memcpy(cmd_line, unix_name.Buffer, unix_name.Length);
5953 + cmd_line[unix_name.Length] = 0;
5954 + c += unix_name.Length + 1;
5955 + p = c;
5956 + RtlFreeAnsiString(&unix_name);
5958 + in_app_name++;
5960 +#else
5961 + *c = (unsigned char)*wc;
5962 + if (*c != '"')
5963 + c++;
5964 +#endif
5966 + *c = 0;
5968 + argv = (char **)malloc(size * sizeof(char *));
5969 + argv[argc++] = cmd_line;
5970 + if (!p)
5971 + p = cmd_line;
5972 + while ((c = strchr(p, ' '))) {
5973 + *c = 0;
5974 + if (p != cmd_line)
5975 + argv[argc++] = p;
5976 + p = c + 1;
5978 + argv[argc++] = p;
5979 + argv[argc] = NULL;
5981 + env_start = (unsigned long)*envp;
5982 + while (*envp++) {
5983 + envc++;
5985 + envp -= 2;
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;
5991 + else {
5992 + last_env = (char *)malloc(strlen(argv[0]) + 2 + 1);
5993 + sprintf(last_env, "_=%s", argv[0]);
5996 + /* fill stack */
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 *));
6001 + /* copy argv0 */
6002 + p -= strlen(*argv) + 1;
6003 + memcpy(p, *argv, strlen(*argv) + 1);
6005 + /* copy environ */
6006 + if (last_env) {
6007 + size = strlen(last_env) + 1;
6008 + p -= size;
6009 + memcpy(p, last_env, size);
6011 + size = env_end - env_start;
6012 + p -= size;
6013 + memcpy(p, (PVOID)env_start, size);
6014 + child_env = p;
6016 + /* copy cmd line */
6017 + i = argc;
6018 + while (--i >= 0) {
6019 + p -= strlen(argv[i]) + 1;
6020 + memcpy(p, argv[i], strlen(argv[i]) + 1);
6022 + child_argv = p;
6023 + size = auxvec_len;
6024 + p -= size;
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;
6033 + *(int *)p = argc;
6034 + p += sizeof(int);
6035 + i = argc;
6036 + c = child_argv;
6037 + while (--i >= 0) {
6038 + *(unsigned long *)p = (unsigned long)c;
6039 + c += strlen(c) + 1;
6040 + p += sizeof(unsigned long);
6042 + *(int *)p = 0;
6043 + p += sizeof(int *);
6044 + i = envc;
6045 + c = child_env;
6046 + while (--i >= 0) {
6047 + *(unsigned long *)p = (unsigned long)c;
6048 + c += strlen(c) + 1;
6049 + p += sizeof(unsigned long);
6051 + *(int *)p = 0;
6052 + p += sizeof(int);
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++)
6063 + tmp[i] += delta;
6065 + envp = tmp + argc + 1;
6066 + tmp = envp;
6067 + while (*tmp) {
6068 + *tmp += delta;
6069 + tmp++;
6072 + ret = NtWriteVirtualMemory(ProcessHandle,
6073 + InitialTeb->StackBase,
6074 + child_stack_start,
6075 + size,
6076 + &size_out
6077 + );
6078 + if (ret)
6079 + goto out;
6081 +out:
6082 + if (cmd_line_w)
6083 + free(cmd_line_w);
6084 + if (cmd_line)
6085 + free(cmd_line);
6086 + if (last_env)
6087 + free(last_env);
6088 + if (stack_u)
6089 + free(stack_u);
6090 + if (argv)
6091 + free(argv);
6093 + return ret;
6096 +extern NTSTATUS WINAPI NtResumeThread( HANDLE handle, PULONG count );
6097 +extern void *_dl_allocate_tls(void *);
6099 +NTSTATUS CDECL
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;
6118 + TEB * teb;
6119 + HANDLE wine_handle;
6120 + BOOLEAN suspend;
6122 + if (!ClientId) {
6123 + CLIENT_ID cid;
6124 + ClientId = &cid;
6126 + /* allocate the stack for the thread */
6127 + nErrCode = RtlRosCreateStack(ProcessHandle,
6128 + &usUserInitialTeb,
6129 + StackZeroBits,
6130 + StackReserve,
6131 + StackCommit);
6133 + /* filure */
6134 + if(nErrCode)
6135 + goto l_Fail;
6137 + if (!BaseStartAddress) {
6138 + nErrCode = RtlRosInitializeStack(ProcessHandle, &usUserInitialTeb);
6139 + if (nErrCode)
6140 + goto l_Fail;
6141 + } else {
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,
6170 + BaseStartAddress,
6171 + &usUserInitialTeb,
6172 + StartAddress,
6173 + Parameter);
6175 + /* failure */
6176 + if(nErrCode)
6177 + goto l_Fail;
6179 + if(BaseStartAddress) suspend = 1;
6180 + else suspend = CreateSuspended;
6182 + /* create the thread object */
6183 + nErrCode = NtCreateThread(ThreadHandle,
6184 + THREAD_ALL_ACCESS,
6185 + ObjectAttributes,
6186 + ProcessHandle,
6187 + ClientId,
6188 + &ctxInitialContext,
6189 + &usUserInitialTeb,
6190 + suspend);
6192 + /* failure */
6193 + if(nErrCode)
6194 + goto l_Fail;
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]);
6216 + SERVER_END_REQ;
6218 + if(nErrCode)
6219 + goto l_Fail;
6221 + if (!store_handle_pair(*ThreadHandle, wine_handle))
6222 + goto l_Fail;
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);
6242 + /* success */
6243 + return STATUS_SUCCESS;
6245 + /* failure */
6246 +l_Fail:
6247 + assert(nErrCode);
6249 + /* deallocate the stack */
6250 + RtlRosDeleteStack(ProcessHandle, &usUserInitialTeb);
6251 + close(request_pipe[1]);
6253 + return nErrCode;
6255 +#endif
6257 /***********************************************************************
6258 * RtlExitUserThread (NTDLL.@)
6259 @@ -618,6 +1471,7 @@
6261 NTSTATUS ret;
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;
6270 SERVER_END_REQ;
6271 +#else
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"
6278 + "int $0x2E\n\t"
6279 + :"=a" (ret)
6280 + );
6282 + if (!ret)
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 );
6290 + if (!ret)
6292 + wine_handle = reply->handle;
6293 + if (!store_handle_pair(*uk_handle, wine_handle))
6294 + return STATUS_NO_MEMORY;
6297 + SERVER_END_REQ;
6299 +#endif
6300 return ret;
6303 @@ -639,12 +1522,36 @@
6305 NTSTATUS ret;
6307 +#ifndef UNIFIED_KERNEL
6308 SERVER_START_REQ( suspend_thread )
6310 req->handle = handle;
6311 if (!(ret = wine_server_call( req ))) *count = reply->count;
6313 SERVER_END_REQ;
6314 +#else
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"
6321 + "int $0x2E\n\t"
6322 + :"=a" (ret)
6323 + );
6324 + if (!ret) {
6325 + pair = search_handle_pair(handle);
6326 + if(pair)
6327 + wine_handle = pair->wine_handle;
6329 + SERVER_START_REQ( suspend_thread )
6331 + req->handle = wine_handle;
6332 + wine_server_call( req );
6334 + SERVER_END_REQ;
6336 +#endif
6337 return ret;
6340 @@ -657,12 +1564,37 @@
6342 NTSTATUS ret;
6344 +#ifndef UNIFIED_KERNEL
6345 SERVER_START_REQ( resume_thread )
6347 req->handle = handle;
6348 if (!(ret = wine_server_call( req ))) *count = reply->count;
6350 SERVER_END_REQ;
6351 +#else
6352 + HANDLE wine_handle = GetCurrentThread();
6353 + struct handle_pair * pair;
6355 + pair = search_handle_pair(handle);
6356 + if(pair)
6357 + wine_handle = pair->wine_handle;
6359 + SERVER_START_REQ( resume_thread )
6361 + req->handle = wine_handle;
6362 + ret = wine_server_call( req );
6364 + SERVER_END_REQ;
6366 + if (!ret) {
6367 + __asm__ __volatile__ (
6368 + "movl $0xA8,%%eax\n\t"
6369 + "lea 8(%%ebp),%%edx\n\t"
6370 + "int $0x2E\n\t"
6371 + :"=a" (ret)
6372 + );
6374 +#endif
6375 return ret;
6378 @@ -696,6 +1628,7 @@
6379 NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
6381 NTSTATUS ret;
6382 +#ifndef UNIFIED_KERNEL
6383 BOOL self, last;
6385 SERVER_START_REQ( terminate_thread )
6386 @@ -713,6 +1646,13 @@
6387 if (last) exit( exit_code );
6388 else server_abort_thread( exit_code );
6390 +#else
6391 + __asm__ __volatile__ ( "movl $0xD4,%%eax\n\t"
6392 + "lea 8(%%ebp),%%edx\n\t"
6393 + "int $0x2E\n\t"
6394 + :"=a" (ret)
6395 + );
6396 +#endif
6397 return ret;
6400 @@ -724,6 +1664,7 @@
6401 ULONG_PTR arg2, ULONG_PTR arg3 )
6403 NTSTATUS ret;
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 );
6411 SERVER_END_REQ;
6412 +#else
6413 + __asm__ __volatile__ (
6414 + "movl $0x95,%%eax\n\t"
6415 + "lea 8(%%ebp),%%edx\n\t"
6416 + "int $0x2E\n\t"
6417 + :"=a" (ret)
6418 + );
6419 +#endif
6420 return ret;
6423 @@ -767,9 +1716,19 @@
6425 if (!self)
6427 +#ifdef UNIFIED_KERNEL
6428 + HANDLE wine_handle = NULL;
6429 + struct handle_pair * pair = search_handle_pair(handle);
6430 + if (pair)
6431 + wine_handle = pair->wine_handle;
6432 +#endif
6433 SERVER_START_REQ( set_thread_context )
6435 +#ifndef UNIFIED_KERNEL
6436 req->handle = handle;
6437 +#else
6438 + req->handle = wine_handle;
6439 +#endif
6440 req->flags = context->ContextFlags;
6441 req->suspend = 0;
6442 wine_server_add_data( req, context, sizeof(*context) );
6443 @@ -1066,9 +2025,19 @@
6445 if (!self)
6447 +#ifdef UNIFIED_KERNEL
6448 + HANDLE wine_handle = NULL;
6449 + struct handle_pair * pair = search_handle_pair(handle);
6450 + if (pair)
6451 + handle = pair->wine_handle;
6452 +#endif
6453 SERVER_START_REQ( get_thread_context )
6455 +#ifndef UNIFIED_KERNEL
6456 req->handle = handle;
6457 +#else
6458 + req->handle = wine_handle;
6459 +#endif
6460 req->flags = context->ContextFlags;
6461 req->suspend = 0;
6462 wine_server_set_reply( req, &ctx, sizeof(ctx) );
6463 @@ -1143,6 +2112,7 @@
6465 NTSTATUS status;
6467 +#ifndef UNIFIED_KERNEL
6468 switch(class)
6470 case ThreadBasicInformation:
6471 @@ -1319,6 +2289,15 @@
6472 FIXME( "info class %d not supported yet\n", class );
6473 return STATUS_NOT_IMPLEMENTED;
6475 +#else
6476 + __asm__ __volatile__ (
6477 + "movl $0x7E,%%eax\n\t"
6478 + "lea 8(%%ebp),%%edx\n\t"
6479 + "int $0x2E\n\t"
6480 + :"=a" (status)
6481 + );
6482 + return status;
6483 +#endif
6487 @@ -1330,6 +2309,7 @@
6488 LPCVOID data, ULONG length )
6490 NTSTATUS status;
6491 +#ifndef UNIFIED_KERNEL
6492 switch(class)
6494 case ThreadZeroTlsCell:
6495 @@ -1430,6 +2410,15 @@
6496 FIXME( "info class %d not supported yet\n", class );
6497 return STATUS_NOT_IMPLEMENTED;
6499 +#else
6500 + __asm__ __volatile__ (
6501 + "movl $0xBB,%%eax\n\t"
6502 + "lea 8(%%ebp),%%edx\n\t"
6503 + "int $0x2E\n\t"
6504 + :"=a" (status)
6505 + );
6506 + return status;
6507 +#endif
6511 @@ -1450,7 +2439,16 @@
6513 TEB * WINAPI NtCurrentTeb(void)
6515 +#ifndef UNIFIED_KERNEL
6516 return pthread_functions.get_current_teb();
6517 +#else
6518 + TEB *ret;
6519 + __asm__ __volatile__ (
6520 + "movl %%fs:0x18, %0\n"
6521 + : "=r" (ret)
6522 + : /* no inputs */ );
6523 + return ret;
6524 +#endif
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 @@
6532 return status;
6535 +#ifdef UNIFIED_KERNEL
6536 +extern void (*ThreadStartup)(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);
6537 +extern NTSTATUS
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);
6549 +#endif
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,
6560 NULL, 0, 0,
6561 worker_thread_proc, NULL, &thread, NULL );
6562 +#else
6563 + status = RtlRosCreateUserThread(GetCurrentProcess(),
6564 + NULL, FALSE, 0, NULL, NULL, (PVOID)ThreadStartup,
6565 + &thread, NULL, (ULONG_PTR)worker_thread_proc, 0);
6566 +#endif
6567 if (status == STATUS_SUCCESS)
6568 NtClose( thread );
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
6573 @@ -84,6 +84,11 @@
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);
6580 +#endif
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 );
6591 +#else
6592 + if (!(view->flags & VFLAG_SYSTEM)) {
6593 + unmap_area( view->base, view->size );
6594 + NtFreeVirtualMemory( NtCurrentProcess(), &view->base, &view->size, MEM_SYSTEM);
6596 +#endif
6597 list_remove( &view->entry );
6598 if (view->mapping) NtClose( view->mapping );
6599 free( view );
6600 @@ -481,6 +493,7 @@
6604 +#ifndef UNIFIED_KERNEL
6605 /***********************************************************************
6606 * VIRTUAL_GetWin32Prot
6608 @@ -493,6 +506,7 @@
6609 if (vprot & VPROT_GUARD) ret |= PAGE_GUARD;
6610 return ret;
6612 +#endif
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 );
6622 +#else
6623 + /* FIXME */
6624 + if (is_beyond_limit( ptr, view_size, (void *)0xc0000000 )) add_reserved_area( ptr, view_size );
6625 +#endif
6626 else break;
6628 ptr = unmap_extra_space( ptr, view_size, size, mask );
6630 done:
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 );
6635 +#endif
6636 if (status != STATUS_SUCCESS) unmap_area( ptr, size );
6637 return status;
6639 @@ -860,6 +883,7 @@
6643 +#ifndef UNIFIED_KERNEL
6644 /***********************************************************************
6645 * decommit_view
6647 @@ -877,6 +901,7 @@
6649 return FILE_GetNtStatus();
6651 +#endif
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
6660 void *base;
6661 BYTE vprot;
6662 SIZE_T size = *size_ptr;
6663 @@ -1489,6 +1515,16 @@
6664 *ret = base;
6665 *size_ptr = size;
6667 +#else
6668 + NTSTATUS status;
6670 + __asm__ __volatile__ (
6671 + "movl $0xB,%%eax\n\t"
6672 + "lea 8(%%ebp),%%edx\n\t"
6673 + "int $0x2E\n\t"
6674 + :"=a" (status)
6675 + );
6676 +#endif
6677 return status;
6680 @@ -1499,6 +1535,7 @@
6682 NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *size_ptr, ULONG type )
6684 +#ifndef UNIFIED_KERNEL
6685 FILE_VIEW *view;
6686 char *base;
6687 sigset_t sigset;
6688 @@ -1583,6 +1620,16 @@
6691 server_leave_uninterrupted_section( &csVirtual, &sigset );
6692 +#else
6693 + NTSTATUS status;
6695 + __asm__ __volatile__ (
6696 + "movl $0x40,%%eax\n\t"
6697 + "lea 8(%%ebp),%%edx\n\t"
6698 + "int $0x2E\n\t"
6699 + :"=a" (status)
6700 + );
6701 +#endif
6702 return status;
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
6710 FILE_VIEW *view;
6711 sigset_t sigset;
6712 NTSTATUS status = STATUS_SUCCESS;
6713 @@ -1668,6 +1716,16 @@
6714 *addr_ptr = base;
6715 *size_ptr = size;
6717 +#else
6718 + NTSTATUS status;
6720 + __asm__ __volatile__ (
6721 + "movl $0x6D,%%eax\n\t"
6722 + "lea 8(%%ebp),%%edx\n\t"
6723 + "int $0x2E\n\t"
6724 + :"=a" (status)
6725 + );
6726 +#endif
6727 return status;
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
6735 FILE_VIEW *view;
6736 char *base, *alloc_base = 0;
6737 struct list *ptr;
6738 @@ -1806,6 +1865,17 @@
6739 info->RegionSize = size - (base - alloc_base);
6740 if (res_len) *res_len = sizeof(*info);
6741 return STATUS_SUCCESS;
6742 +#else
6743 + NTSTATUS status;
6745 + __asm__ __volatile__ (
6746 + "movl $0x93,%%eax\n\t"
6747 + "lea 8(%%ebp),%%edx\n\t"
6748 + "int $0x2E\n\t"
6749 + :"=a" (status)
6750 + );
6751 + return status;
6752 +#endif
6756 @@ -1882,6 +1952,119 @@
6757 return status;
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 )
6765 + NTSTATUS ret;
6766 + __asm__ __volatile__ (
6767 + "movl $0x24,%%eax\n\t"
6768 + "lea 8(%%ebp),%%edx\n\t"
6769 + "int $0x2E\n\t"
6770 + :"=a" (ret)
6771 + );
6772 + return ret;
6775 +NTSTATUS WINAPI UkOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
6777 + NTSTATUS ret;
6778 + __asm__ __volatile__ (
6779 + "movl $0x61,%%eax\n\t"
6780 + "lea 8(%%ebp),%%edx\n\t"
6781 + "int $0x2E\n\t"
6782 + :"=a" (ret)
6783 + );
6784 + return ret;
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 )
6791 + NTSTATUS ret;
6792 + __asm__ __volatile__ (
6793 + "movl $0x52,%%eax\n\t"
6794 + "lea 8(%%ebp),%%edx\n\t"
6795 + "int $0x2E\n\t"
6796 + :"=a" (ret)
6797 + );
6798 + return ret;
6801 +NTSTATUS WINAPI UkUnmapViewOfSection( HANDLE process, PVOID addr )
6803 + NTSTATUS ret;
6804 + __asm__ __volatile__ (
6805 + "movl $0xdc,%%eax\n\t"
6806 + "lea 8(%%ebp),%%edx\n\t"
6807 + "int $0x2E\n\t"
6808 + :"=a" (ret)
6809 + );
6810 + return ret;
6813 +NTSTATUS WINAPI UkQuerySection(
6814 + IN HANDLE SectionHandle,
6815 + IN SECTION_INFORMATION_CLASS SectionInformationClass,
6816 + OUT PVOID SectionInformation,
6817 + IN ULONG Length,
6818 + OUT PULONG ResultLength)
6820 + NTSTATUS ret;
6821 + __asm__ __volatile__(
6822 + "movl $0x89,%%eax\n\t"
6823 + "lea 8(%%ebp),%%edx\n\t"
6824 + "int $0x2E\n\t"
6825 + :"=a" (ret)
6826 + );
6827 + return ret;
6830 +NTSTATUS WINAPI UkAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_bits,
6831 + SIZE_T *size_ptr, ULONG type, ULONG protect )
6833 + NTSTATUS status;
6835 + __asm__ __volatile__ (
6836 + "movl $0xB,%%eax\n\t"
6837 + "lea 8(%%ebp),%%edx\n\t"
6838 + "int $0x2E\n\t"
6839 + :"=a" (status)
6840 + );
6841 + return status;
6844 +NTSTATUS WINAPI UkWriteVirtualMemory( HANDLE process, void *addr, const void *buffer,
6845 + SIZE_T size, SIZE_T *bytes_written )
6847 + NTSTATUS status;
6849 + __asm__ __volatile__ (
6850 + "movl $0xE5,%%eax\n\t"
6851 + "lea 8(%%ebp),%%edx\n\t"
6852 + "int $0x2E\n\t"
6853 + :"=a" (status)
6854 + );
6855 + return status;
6858 +NTSTATUS WINAPI UkReadVirtualMemory( HANDLE process, const void *addr, void *buffer,
6859 + SIZE_T size, SIZE_T *bytes_read )
6861 + NTSTATUS status;
6863 + __asm__ __volatile__ (
6864 + "movl $0x9B,%%eax\n\t"
6865 + "lea 8(%%ebp),%%edx\n\t"
6866 + "int $0x2E\n\t"
6867 + :"=a" (status)
6868 + );
6869 + return status;
6872 +#endif
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
6881 NTSTATUS ret;
6882 BYTE vprot;
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 );
6890 +#else
6891 + ret = NtWineService( req );
6892 +#endif
6893 *handle = reply->handle;
6895 SERVER_END_REQ;
6896 @@ -1939,6 +2127,16 @@
6897 NTDLL_free_struct_sd( sd );
6899 return ret;
6900 +#else
6901 + NTSTATUS ret;
6902 + __asm__ __volatile__ (
6903 + "movl $0x24,%%eax\n\t"
6904 + "lea 8(%%ebp),%%edx\n\t"
6905 + "int $0x2E\n\t"
6906 + :"=a" (ret)
6907 + );
6908 + return ret;
6909 +#endif
6913 @@ -1948,6 +2146,7 @@
6915 NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
6917 +#ifndef UNIFIED_SECTION
6918 NTSTATUS ret;
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;
6927 +#else
6928 + if (!(ret = NtWineService( req ))) *handle = reply->handle;
6929 +#endif
6931 SERVER_END_REQ;
6932 return ret;
6933 +#else
6934 + NTSTATUS ret;
6935 + __asm__ __volatile__ (
6936 + "movl $0x61,%%eax\n\t"
6937 + "lea 8(%%ebp),%%edx\n\t"
6938 + "int $0x2E\n\t"
6939 + :"=a" (ret)
6940 + );
6941 + return ret;
6942 +#endif
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
6951 NTSTATUS res;
6952 ULONGLONG full_size;
6953 SIZE_T size = 0;
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 );
6960 +#else
6961 + res = NtWineService( req );
6962 +#endif
6963 prot = reply->protect;
6964 base = reply->base;
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 );
6972 +#endif
6973 NtClose( shared_file );
6975 else
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 );
6982 +#endif
6983 if (!res) *size_ptr = size;
6984 return res;
6986 @@ -2142,8 +2364,19 @@
6988 done:
6989 if (dup_mapping) NtClose( dup_mapping );
6990 +#ifndef UNIFIED_KERNEL
6991 if (needs_close) close( unix_handle );
6992 +#endif
6993 return res;
6994 +#else
6995 + NTSTATUS ret;
6996 + __asm__ __volatile__ (
6997 + "movl $0x52,%%eax\n\t"
6998 + "lea 8(%%ebp),%%edx\n\t"
6999 + "int $0x2E\n\t"
7000 + :"=a" (ret)
7001 + );
7002 +#endif
7006 @@ -2153,6 +2386,7 @@
7008 NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
7010 +#ifndef UNIFIED_SECTION
7011 FILE_VIEW *view;
7012 NTSTATUS status = STATUS_INVALID_PARAMETER;
7013 sigset_t sigset;
7014 @@ -2180,6 +2414,16 @@
7016 server_leave_uninterrupted_section( &csVirtual, &sigset );
7017 return status;
7018 +#else
7019 + NTSTATUS ret;
7020 + __asm__ __volatile__ (
7021 + "movl $0xdc,%%eax\n\t"
7022 + "lea 8(%%ebp),%%edx\n\t"
7023 + "int $0x2E\n\t"
7024 + :"=a" (ret)
7025 + );
7026 + return ret;
7027 +#endif
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
7036 FILE_VIEW *view;
7037 NTSTATUS status = STATUS_SUCCESS;
7038 sigset_t sigset;
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 );
7043 +#else
7044 + NTSTATUS status;
7046 + __asm__ __volatile__ (
7047 + "movl $0x3E,%%eax\n\t"
7048 + "lea 8(%%ebp),%%edx\n\t"
7049 + "int $0x2E\n\t"
7050 + :"=a" (status)
7051 + );
7052 +#endif
7053 return status;
7056 @@ -2238,6 +2493,7 @@
7058 NTSTATUS status;
7060 +#ifndef UNIFIED_KERNEL
7061 SERVER_START_REQ( read_process_memory )
7063 req->handle = process;
7064 @@ -2247,6 +2503,14 @@
7066 SERVER_END_REQ;
7067 if (bytes_read) *bytes_read = size;
7068 +#else
7069 + __asm__ __volatile__ (
7070 + "movl $0x9B,%%eax\n\t"
7071 + "lea 8(%%ebp),%%edx\n\t"
7072 + "int $0x2E\n\t"
7073 + :"=a" (status)
7074 + );
7075 +#endif
7076 return status;
7079 @@ -2260,6 +2524,7 @@
7081 NTSTATUS status;
7083 +#ifndef UNIFIED_KERNEL
7084 SERVER_START_REQ( write_process_memory )
7086 req->handle = process;
7087 @@ -2269,6 +2534,14 @@
7089 SERVER_END_REQ;
7090 if (bytes_written) *bytes_written = size;
7091 +#else
7092 + __asm__ __volatile__ (
7093 + "movl $0xE5,%%eax\n\t"
7094 + "lea 8(%%ebp),%%edx\n\t"
7095 + "int $0x2E\n\t"
7096 + :"=a" (status)
7097 + );
7098 +#endif
7099 return status;
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
7113 + */
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;
7120 + int i, sec_align;
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;
7127 + virtual_init();
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)
7139 + return status;
7141 + view->flags |= VFLAG_VALLOC;
7142 + return status;
7144 +#endif
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
7148 @@ -439,7 +439,9 @@
7149 else
7151 RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
7152 +#ifndef UNIFIED_KERNEL /* FIXME */
7153 WIN_SetStyle( hwnd, 0, WS_VISIBLE );
7154 +#endif
7156 return 0;
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 @@
7162 if (modal)
7164 ownerEnabled = DIALOG_DisableOwner( owner );
7165 +#ifndef UNIFIED_KERNEL
7166 if (ownerEnabled) flags |= DF_OWNERENABLED;
7167 +#else
7168 + if (ownerEnabled || owner == GetActiveWindow()) flags |= DF_OWNERENABLED;
7169 +#endif
7172 if (unicode)
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] == ' '))
7178 index--;
7179 if (index) {
7180 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7181 while (index && (s[index] != ' '))
7182 index--;
7183 if (s[index] == ' ')
7184 index++;
7185 +#else
7186 + if (!(s[index] & 0xFF00)) {
7187 + while (index && (s[index] != ' ') && !(s[index] & 0xFF00))
7188 + index--;
7189 + if (s[index] & 0xFF00)
7190 + index++;
7192 + if (s[index] == ' ')
7193 + index++;
7194 +#endif
7196 } else {
7197 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7198 while (index && (s[index] != ' '))
7199 index--;
7200 if (s[index] == ' ')
7201 index++;
7202 +#else
7203 + if (!(s[index] & 0xFF00)) {
7204 + while (index && (s[index] != ' ') && !(s[index] & 0xFF00))
7205 + index--;
7206 + if (s[index] & 0xFF00)
7207 + index++;
7209 + if (s[index] == ' ')
7210 + index++;
7211 +#endif
7213 ret = index;
7214 break;
7215 @@ -2616,8 +2638,17 @@
7216 if (s[index] == ' ')
7217 while ((index < count) && (s[index] == ' ')) index++;
7218 else {
7219 +#ifndef UNIFIED_KERNEL /* modified for 16-bit character break */
7220 while (s[index] && (s[index] != ' ') && (index < count))
7221 index++;
7222 +#else
7223 + if (!(s[index] & 0xFF00))
7224 + while (s[index] && (s[index] != ' ')
7225 + && (index < count) && !(s[index] & 0xFF00))
7226 + index++;
7227 + else
7228 + index++;
7229 +#endif
7230 while ((s[index] == ' ') && (index < count)) index++;
7232 ret = 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);
7242 return 0;
7243 +#else
7244 + MDICLIENTINFO *ci;
7245 + HWND *win_array;
7246 + BOOL has_icons = FALSE;
7247 + int i, total;
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 );
7257 + return 0;
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] ))
7267 + has_icons = TRUE;
7268 + continue;
7271 + total++;
7273 + HeapFree( GetProcessHeap(), 0, win_array );
7275 + if(lpKids)
7277 + if (ci->nActiveChildren == 0)
7279 + HeapFree( GetProcessHeap(), 0, ci );
7280 + return 0;
7283 + if (cKids)
7285 + HWND *tmpid;
7286 + INT delta = 0, n = 0, i;
7287 + POINT pos[2];
7289 + if (has_icons)
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 );
7308 + return cKids;
7310 + else
7312 + /* cascade child windows */
7313 + MDICascade(hwndParent, ci);
7315 + HeapFree( GetProcessHeap(), 0, ci );
7316 + return total;
7318 +#endif
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);
7328 return 0;
7329 +#else
7330 + /* Arrange child windows horizontally or vertically
7331 + Compare child windows abreast */
7332 + MDICLIENTINFO *ci;
7333 + HWND hwndChild;
7334 + BOOL has_icons = FALSE;
7335 + int total;
7337 + if (!(ci = get_client_info(hwndParent)))
7338 + return 0;
7340 + for (hwndChild = GetTopWindow(hwndParent), total = 0; hwndChild != NULL;
7341 + hwndChild = GetNextWindow(hwndChild, GW_HWNDNEXT)) {
7342 + if (!IsWindowVisible(hwndChild))
7343 + continue;
7344 + if (GetWindow(hwndChild, GW_OWNER))
7345 + continue;
7346 + if (IsIconic(hwndChild)) {
7347 + has_icons = TRUE;
7348 + continue;
7350 + if ((wFlags & MDITILE_SKIPDISABLED) && !IsWindowEnabled(hwndChild))
7351 + continue;
7353 + total++;
7356 + if (!lpKids) {
7357 + MDITile(hwndParent, ci, wFlags);
7359 + HeapFree(GetProcessHeap(), 0, ci);
7360 + return total;
7362 + else {
7363 + /* Refered to MDITile() */
7364 + HWND *pWnd = (HWND *)lpKids;
7365 + RECT rect;
7366 + int x, y, xsize, ysize;
7367 + int rows, columns, r, c, i;
7369 + if (cKids <= 0) {
7370 + HeapFree(GetProcessHeap(), 0, ci);
7371 + return 0;
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) {
7382 + i = rows;
7383 + rows = columns;
7384 + columns = i;
7387 + if (has_icons) {
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) {
7398 + rows = cKids - i;
7399 + ysize = rect.bottom / rows;
7402 + y = 0;
7403 + for (r = 1; r <= rows && *pWnd; r++, i++) {
7404 + SetWindowPos(*pWnd, 0, x, y, xsize, ysize,
7405 + SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
7406 + y += ysize;
7407 + pWnd++;
7409 + x += xsize;
7411 + HeapFree(GetProcessHeap(), 0, ci);
7413 + if (has_icons)
7414 + ArrangeIconicWindows(hwndParent);
7415 + return cKids;
7417 +#endif
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
7424 @@ -43,6 +43,9 @@
7425 #include "win.h"
7426 #include "controls.h"
7427 #include "wine/debug.h"
7428 +#ifdef UNIFIED_KERNEL
7429 +#include "handle.h"
7430 +#endif
7432 WINE_DEFAULT_DEBUG_CHANNEL(msg);
7433 WINE_DECLARE_DEBUG_CHANNEL(relay);
7434 @@ -3254,6 +3257,11 @@
7435 DWORD start_time, elapsed, ret;
7436 HANDLE handles[2];
7438 +#ifdef UNIFIED_KERNEL
7439 + struct handle_pair* pair = search_handle_pair(hProcess);
7440 + if (pair)
7441 + hProcess = pair->wine_handle;
7442 +#endif
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: , . ? ! ) >> ' ' " ; : */
7457 + if (
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) */
7470 + p--;
7471 + /* CJK characters are treated breakable */
7472 + p--;
7474 +#endif
7475 else
7477 +#ifndef UNIFIED_KERNEL
7478 while (p > str && *(--p) != SPACE)
7480 +#else
7481 + /* if Chinese and English mix up */
7482 + while (p > str && *p != SPACE && (*p < 0x3012 || *p > 0xFA29 ) )
7483 + p--;
7484 +#endif
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 @@
7492 POINT size;
7493 LONG old_style;
7494 WINDOWPLACEMENT wpl;
7495 +#ifdef UNIFIED_KERNEL
7496 + HWND parent;
7497 + RECT parent_rect;
7498 +#endif
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);
7508 + if (parent)
7509 + SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
7510 + parent_rect.right - parent_rect.left, parent_rect.bottom - parent_rect.top);
7511 + else
7512 + SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
7513 +#else
7514 SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
7515 +#endif
7516 break;
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 ))
7525 count++;
7526 +#ifndef UNIFIED_KERNEL
7527 if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */
7528 +#else
7529 + if(event.type != KeyRelease) /* do not filter key release event */
7531 + if (XFilterEvent( &event, None )==True) continue; /* filtered, ignore it */
7533 +#endif
7534 if (prev_event.type) action = merge_events( &prev_event, &event );
7535 switch( action )
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
7540 @@ -51,8 +51,155 @@
7541 BOOL result = TRUE;
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);
7547 +#else
7548 + if(physDev->has_gdi_font)
7550 + HDC hdc;
7551 + TEXTMETRICW tmw;
7553 + /* get tmw */
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)
7567 + int font_heigh;
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 )
7577 + while(font_heigh)
7579 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 1),
7580 + y + (int)(font_heigh * 0.3),
7581 + flags, lprect, wstr, count, lpDx);
7583 + --font_heigh;
7587 + else if(tmw.tmHeight <= 720)
7589 + while(font_heigh)
7591 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.7),
7592 + y + (int)(font_heigh * 0.3),
7593 + flags, lprect, wstr, count, lpDx);
7595 + --font_heigh;
7597 + }
7598 + else
7600 + font_heigh = (font_heigh*0.5);
7601 + while(font_heigh)
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);
7609 + /* prettier
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);
7618 + */
7619 + --font_heigh;
7622 + } /* end bold_flag2 */
7623 + } /* if !rotate */
7624 + else
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)
7634 + int font_heigh;
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 )
7643 + while(font_heigh)
7645 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.3),
7646 + y + (int)(font_heigh * 1),
7647 + flags, lprect, wstr, count, lpDx);
7649 + --font_heigh;
7653 + else if(tmw.tmHeight <= 720)
7655 + while(font_heigh)
7657 + X11DRV_XRender_ExtTextOut(physDev, x + (int)(font_heigh * 0.3),
7658 + y + (int)(font_heigh * 0.7),
7659 + flags, lprect, wstr, count, lpDx);
7661 + --font_heigh;
7663 + }
7664 + else
7666 + font_heigh = (font_heigh*0.5);
7667 + while(font_heigh)
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);
7675 + /* prettier
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);
7684 + */
7685 + --font_heigh;
7688 + } /* end flag2 */
7689 + } /* if rotate */
7690 + return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx);
7692 +#endif
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 @@
7701 if (path)
7703 +#ifndef UNIFIED_KERNEL /* modify for dragging file with Chinese file name */
7704 int pathSize = strlenW(path) + 1;
7705 +#else
7706 + int pathSize = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, 0, 0);
7707 +#endif
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
7714 @@ -0,0 +1,59 @@
7716 + * handle.h
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).
7723 + *
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.
7735 + */
7738 + * handle.h: We use Unified Kernel handles to make it compatible with Wine's
7739 + * operations.
7740 + */
7742 +#ifndef __UK_HANDLE_H
7743 +#define __UK_HANDLE_H
7745 +#ifdef UNIFIED_KERNEL
7746 +#include "wine/list.h"
7748 +/*
7749 + * if the handle value greater than (1<<15), it will fault when someone
7750 + * call it
7751 + */
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)
7761 +struct handle_pair
7763 + struct list entry;
7764 + HANDLE uk_handle;
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);
7783 +#else
7784 +VOID WINAPI ExitThread(DWORD);
7785 +#endif
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
7792 @@ -488,6 +488,9 @@
7793 unsigned int attributes;
7794 int suspend;
7795 int request_fd;
7796 +#ifdef UNIFIED_KERNEL
7797 + int tid;
7798 +#endif
7800 struct new_thread_reply
7802 @@ -541,6 +544,10 @@
7803 void* ldt_copy;
7804 int reply_fd;
7805 int wait_fd;
7806 +#ifdef UNIFIED_KERNEL
7807 + int pid;
7808 + int tid;
7809 +#endif
7811 struct init_thread_reply
7813 @@ -1070,6 +1077,7 @@
7814 int removable;
7815 unsigned int access;
7816 unsigned int options;
7817 + int fd;
7819 enum server_fd_type
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
7832 +#endif
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*);
7842 +#else
7843 +BOOL WINAPI ExtTextOutW(HDC,INT,INT,UINT,const RECT*,
7844 + LPWSTR,UINT,const INT*);
7845 +#endif
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);
7858 +#else
7859 +void WINAPI RtlExitUserThread(ULONG);
7860 +#endif
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
7867 @@ -424,6 +424,7 @@
7868 #ifdef linux
7869 if (use_preloader)
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 @@
7876 free( new_argv );
7877 free( full_name );
7878 return;
7879 +#else
7880 + char *p;
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) );
7886 + if(!new_argv)
7887 + return;
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) {
7894 + free(new_argv);
7895 + return;
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");
7902 + else {
7903 + if(strcmp(p, ".exe") == 0) {
7904 + strcat(new_argv[0], ".so");
7909 + execv( new_argv[0], new_argv );
7910 + free( new_argv );
7911 + return;
7912 +#endif
7914 #endif
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 )
7925 +#else
7926 +void parse_options( const char *str )
7927 +#endif
7929 char *opt, *next, *options;
7930 unsigned int i;
7931 @@ -169,7 +173,11 @@
7934 /* print the usage message */
7935 +#ifndef UNIFIED_KERNEL
7936 static void debug_usage(void)
7937 +#else
7938 +void debug_usage(void)
7939 +#endif
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
7946 @@ -91,7 +91,11 @@
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)
7952 +#else
7953 +void build_dll_path(void)
7954 +#endif
7956 int len, count = 0;
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 )
7964 +#else
7965 +void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
7966 +#endif
7968 #ifdef HAVE_MMAP
7969 IMAGE_DATA_DIRECTORY *dir;
7970 @@ -807,3 +815,10 @@
7971 return 1;
7972 #endif
7975 +#ifdef UNIFIED_KERNEL_EXESO
7976 +IMAGE_NT_HEADERS **get_main_exe_ptr()
7978 + return (IMAGE_NT_HEADERS **)&main_exe;
7980 +#endif
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
7984 @@ -7,7 +7,8 @@
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
7992 VERSION = 1.0
7993 SOVERSION = 1
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();
8006 +#endif
8008 /***********************************************************************
8009 * mmap_init
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 @@
8014 wine_utf8_mbstowcs;
8015 wine_utf8_wcstombs;
8016 wine_wctype_table;
8017 + build_dll_path;
8018 + debug_usage;
8019 + parse_options;
8020 + get_dlldir;
8021 + get_main_exe_ptr;
8022 + map_dll;
8023 + uk_reserve_dos_area;
8025 local: *;
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";
8042 + if (argc <= 1)
8044 + fprintf( stderr, "%s\n", usage );
8045 + exit(1);
8047 + if (!strcmp( argv[1], "--help" ))
8049 + printf( "%s\n", usage);
8050 + exit(0);
8052 + if (!strcmp( argv[1], "--version" ))
8054 + printf( "%s\n", wine_get_build_id() );
8055 + exit(0);
8058 +#endif
8060 /**********************************************************************
8061 * main
8063 @@ -121,6 +147,9 @@
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 );
8069 +#endif
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
8076 @@ -1,3 +1,4 @@
8077 +DEFS = -DUNIFIED_KERNEL
8078 TOPSRCDIR = @top_srcdir@
8079 TOPOBJDIR = ..
8080 SRCDIR = @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 @@
8086 if (p2 && *p2)
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);
8091 +#else
8092 + LPWSTR quotationW = NULL;
8093 + int len = strlenW(p2);
8095 + quotationW = HeapAlloc(GetProcessHeap(), 0, (len + 3) * sizeof(WCHAR));
8096 + if (quotationW) {
8097 + quotationW[0] = '\"';
8098 + strcpyW(&quotationW[1], p2);
8099 + quotationW[len + 1] = '\"';
8100 + quotationW[len + 2] = 0;
8101 + CopyPathString(parameters->root,quotationW);
8102 + HeapFree(GetProcessHeap(), 0, quotationW);
8104 +#endif
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
8111 @@ -10,7 +10,7 @@
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
8123 @@ -533,6 +533,7 @@
8124 return name;
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 @@
8133 return r;
8135 +#endif
8137 DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *service_argv)
8139 DWORD err;
8140 LPWSTR name;
8141 +#ifndef UNIFIED_KERNEL
8142 HANDLE process_handle = NULL;
8143 +#endif
8145 err = scmdatabase_lock_startup(service->db);
8146 if (err != ERROR_SUCCESS)
8147 @@ -709,6 +713,7 @@
8148 return GetLastError();
8151 +#ifndef UNIFIED_KERNEL
8152 err = service_start_process(service, &process_handle);
8154 if (err == ERROR_SUCCESS)
8155 @@ -722,6 +727,7 @@
8157 if (process_handle)
8158 CloseHandle(process_handle);
8159 +#endif
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
8166 @@ -34,6 +34,10 @@
8167 #include "winefile.h"
8168 #include "resource.h"
8170 +#ifdef UNIFIED_KERNEL
8171 +#include "wine/library.h"
8172 +#endif
8174 #ifdef _NO_EXTENSIONS
8175 #undef _LEFT_FILES
8176 #endif
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];
8184 + int i;
8185 +#endif
8187 if (!entry)
8188 return;
8189 @@ -3807,6 +3816,22 @@
8190 if (path[0])
8191 if (SetCurrentDirectory(path))
8192 set_space_status();
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);
8208 +#endif
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);
8221 +#else
8222 + /* convert the path passed to wineshelllink into unix format */
8223 + escaped_path = wine_get_unix_file_name( szPath );
8224 +#endif
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
8231 @@ -1,4 +1,4 @@
8232 -DEFS = -D__WINESRC__
8233 +DEFS = -D__WINESRC__ -DUNIFIED_KERNEL
8234 TOPSRCDIR = @top_srcdir@
8235 TOPOBJDIR = ..
8236 SRCDIR = @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)
8248 +#endif
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 @@
8254 return id;
8257 +#ifdef UNIFIED_KERNEL
8259 + * store_ptid:
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.
8263 + */
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];
8271 + else
8273 + unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2);
8274 + if (!count)
8275 + count = 64;
8276 + if (!(entry = realloc(ptid_entries, count * sizeof(*entry))))
8277 + return 0;
8279 + ptid_entries = entry;
8280 + alloc_ptid_entries = count;
8281 + entry = &ptid_entries[index];
8283 + used_ptid_entries++;
8284 + entry->ptr = ptr;
8285 + return index;
8287 +#endif
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];
8295 entry->ptr = NULL;
8296 @@ -201,14 +240,28 @@
8297 else next_free_ptid = id;
8299 last_free_ptid = id;
8300 +#else
8301 + struct ptid_entry *entry = &ptid_entries[PTID_TO_INDEX(id)];
8303 + entry->ptr = NULL;
8304 + entry->next = 0;
8305 + used_ptid_entries--;
8306 +#endif
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;
8316 +#else
8317 + int index = PTID_TO_INDEX(id);
8318 + if ((id % 4) || (index <= 0))
8319 + return NULL;
8320 + return ptid_entries[index].ptr;
8321 +#endif
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 )))
8332 close( fd );
8333 goto error;
8335 +#else
8336 + process->id = process->group_id = 0;
8337 +#endif
8338 if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj, 0 ))) goto error;
8340 /* create the handle table */
8341 @@ -426,7 +483,9 @@
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 );
8347 +#endif
8348 if (process->token) release_object( process->token );
8351 @@ -594,6 +653,9 @@
8352 if (thread == skip) break;
8353 kill_thread( thread, 1 );
8355 +#ifdef UNIFIED_KERNEL
8356 + if (process->id) free_ptid( process->id );
8357 +#endif
8358 release_object( process );
8361 @@ -747,6 +809,9 @@
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 );
8367 +#endif
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 );
8378 +#endif
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 );
8388 +#endif
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
8395 @@ -50,6 +50,10 @@
8396 #include "security.h"
8399 +#ifdef UNIFIED_KERNEL
8400 +extern int store_ptid(unsigned int id, void *ptr);
8401 +#endif
8403 /* thread queues */
8405 struct thread_wait
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 );
8414 return NULL;
8416 +#else
8417 + thread->id = 0;
8418 +#endif
8419 if (!(thread->request_fd = create_anonymous_fd( &thread_fd_ops, fd, &thread->obj, 0 )))
8421 release_object( thread );
8422 @@ -281,7 +289,9 @@
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 );
8428 +#endif
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 );
8438 +#else
8439 + thread->suspend++;
8440 +#endif
8442 else set_error( STATUS_SUSPEND_COUNT_EXCEEDED );
8443 return old_count;
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 );
8450 +#else
8451 + thread->suspend--;
8452 +#endif
8454 return old_count;
8456 @@ -916,17 +934,24 @@
8457 if (thread->wait)
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 */
8463 violent_death = 0;
8464 +#endif
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 );
8472 +#endif
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 );
8477 +#endif
8478 release_object( thread );
8481 @@ -995,6 +1020,12 @@
8483 if ((thread = create_thread( request_fd, current->process )))
8485 +#ifdef UNIFIED_KERNEL
8486 + if(req->tid){
8487 + thread->id = req->tid;
8488 + store_ptid(thread->id, thread);
8490 +#endif
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);
8508 +#endif
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 );
8518 +#endif
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 @@
8524 reply->self = 1;
8525 reply->last = (thread->process->running_threads == 1);
8526 +#ifdef UNIFIED_KERNEL
8527 + if (thread->id) free_ptid( thread->id );
8528 +#endif
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
8535 @@ -87,7 +87,7 @@
8536 cat <<EOF
8537 [Desktop Entry]
8538 Name=$linkname
8539 -Exec=env WINEPREFIX="${WINEPREFIX:-$HOME/.wine}" wine "$path" $args
8540 +Exec="$path" $args
8541 Type=Application
8542 StartupWMClass=Wine