diff --git a/ANNOUNCE b/ANNOUNCE index 6485e58626..64fa51771d 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,12 +1,14 @@ -This is release 960324 of Wine the MS Windows emulator. This is still a +This is release 960331 of Wine the MS Windows emulator. This is still a developer's only release. There are many bugs and many unimplemented API features. Most applications still do not work. Patches should be submitted to "julliard@lrc.epfl.ch". Please don't forget to include a ChangeLog entry. -WHAT'S NEW with Wine-960324: (see ChangeLog for details) - - Many Win32 and Winelib improvements. +WHAT'S NEW with Wine-960331: (see ChangeLog for details) + - Many improvements to keyboard handling. + - New registry code with Win32 support. + - Support for Italian language. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -15,10 +17,10 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960324.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960324.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960324.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-960324.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960331.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960331.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960331.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-960331.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index 687c40231d..88685439e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,123 @@ +---------------------------------------------------------------------- +Sun Mar 31 13:54:46 1996 Alexandre Julliard + + * [tools/build.c] + Changed BuildSpec32Files() to generate assembly instead of C code. + Unified -spec16 and -spec32 options; DLL type is now determined by + the 'type' declaration in the .spec file. + New -stdcall option to build all stdcall assembly relays. + + * [if1632/relay.c] [if1632/relay32.c] [include/dlls.h] + Started to unify 16- and 32-bit builtin DLLs. + + * [loader/module.c] + Added MODULE_GetWndProcEntry32() to mirror MODULE_GetWndProcEntry16(). + + * [loader/pe_image.c] [loader/resource.c] + All modules now have a NE signature, and can be distinguished by + the NE_FFLAGS_WIN32 flag. + + * [windows/alias.c] + Aliases for built-in window procedures are now all created at + startup in ALIAS_Init(). + +Fri Mar 29 14:56:39 1996 Greg Kreider + + * [controls/combo.c] + Limit rectangle to clear to size of item when painting combo, not + default. Only draw items in list when there is enough room for them. + + * [controls/listbox.c] + Get the measure of every item that's added and store in the item's + data structure. Scroll listbox if mouse near edge of box. Only + draw items in list when there is enough room. + +Fri Mar 29 12:00:00 1996 Alex Korobka + + * [windows/defwnd.c] [windows/dialog.c] [windows/mdi.c] + [windows/nonclient.c] [controls/menu.c] + Various changes for better keyboard handling. + + * [windows/event.c] [windows/message.c] [misc/keyboard.c] + Proper keyboard message ordering, working GetKeyState() (finally!), + improvements in ToAscii(). + + * [windows/win.c] [windows/message.c] + Small improvements in WIN_FindWinToRepaint. + + * [windows/win.c] [windows/painting.c] [windows/nonclient.c] + Put update region in WM_NCPAINT wParam. + + * [loader/task.c] + Kill task timers when task is deleted, switch timers to the + new queue in SetTaskQueue(). + + * [loader/signal.c] [miscemu/dosmem.c] + Added SIGALRM signal handler to increment BIOS clock. + + * [windows/win.c] [windows/winpos.c] [windows/mdi.c] + Fixed ChildWindowFromPoint(), WM_PARENTNOTIFY and its handling by + MDI client. + + * [windows/winpos.c] + Improvements in handling of owned popups. "Floating" toolboxes + work better now. + +Thu Mar 28 12:38:29 1996 Marcus Meissner + + * [misc/registry.c] + New file, registry rewrite including win32 extensions + - Unicode + - multiple valus per key + - different datatypes for values + - multiple rootkeys + - saving and loading in different registries. + + * [include/winreg.h] + New file, definitions and structs for registry. + + * [include/winerror.h] + Some new error defines added... there are more, someone please + check a (real-)windows winerror.h. + + * [if1632/shell.spec] [if1632/advapi32.spec] [if1632/kernel.spec] + Registry specs added. + + * [if1632/relay.c] + Switch internal SHELL.DLL to default 'used'. + + * [win32/string32.c] [include/string32.h] + Some new functions added. + char should be unsigned char when converting to 16bit ints. + + * [misc/shell.c] [include/shell.h] [win32/advapi.c] + Removed old registry functions. + +Tue Mar 26 15:01:46 1996 Frans van Dorsselaer + + * [include/bitmaps/ocr_ibeam] + Fixed the position of the hotspot. + + * [objects/text.c] + Fixed a few bugs in TEXT_TabbedTextOut(). + + * [windows/event.c] + Fixed the order of the bits in the KeyStateTable. + 0x80 is the up/down-bit. 0x01 is the toggle bit. + + * [loader/resource.c] [windows/mdi.c] [controls/edit.c] + Fixed the calls to GetKeyState(). + +Tue Mar 26 08:43:15 1996 Robert Pouliot + + * [resources/sysres_Fr.rc] [resources/TODO] + Updated FIND_TEXT and REPLACE_TEXT to work like the English version. + +Mon Mar 25 17:38:59 1996 Tristan Tarrant + + * [resources/sysres_it.rc] + Added support for Italian [It] language. + ---------------------------------------------------------------------- Sun Mar 24 13:13:11 1996 Alexandre Julliard diff --git a/Make.rules.in b/Make.rules.in index 3ae1d05c2e..b07b131ca5 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -16,7 +16,7 @@ YACC = @YACC@ LEX = @LEX@ LEXLIB = @LEXLIB@ DIVINCL = -I$(TOPSRC)/include -ALLCFLAGS = $(CFLAGS) $(DEFS) $(X_CFLAGS) $(DIVINCL) $(EXTRA_DEFS) +ALLCFLAGS = $(CFLAGS) $(DEFS) $(DIVINCL) $(X_CFLAGS) $(EXTRA_DEFS) LDCOMBINE = ld -r RM = rm -f BUILD = $(TOPSRC)/tools/build diff --git a/controls/combo.c b/controls/combo.c index f637b0fe6b..8ac780f58d 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -235,21 +235,17 @@ static LRESULT CBPaint(HWND hwnd, WPARAM wParam, LPARAM lParam) GetClientRect(hwnd, &rect); rect.right -= (lphc->RectButton.right - lphc->RectButton.left); - FillRect(hdc, &rect, hBrush); lpls = ListBoxGetItem(lphl,lphl->ItemFocused); if (lpls != NULL) { height = lpls->mis.itemHeight; rect.bottom = rect.top + height; - - if (lphl->OwnerDrawn) { - ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0); - } else { - ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0); - } + FillRect(hdc, &rect, hBrush); + ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0); if (GetFocus() == hwnd) ListBoxDrawItem (hwnd,lphl, hdc, lpls, &rect, ODA_FOCUS, ODS_FOCUS); } + else FillRect(hdc, &rect, hBrush); SelectObject(hdc,hOldFont); EndPaint(hwnd, &ps); return 0; @@ -774,8 +770,9 @@ static LRESULT CBLPaint( HWND hwnd, WPARAM wParam, LPARAM lParam ) if (i >= lphl->FirstVisible) { height = lpls->mis.itemHeight; + /* must have enough room to draw entire item */ + if (top > (rect.bottom-height+1)) break; - if (top > rect.bottom) break; lpls->itemRect.top = top; lpls->itemRect.bottom = top + height; lpls->itemRect.left = rect.left; diff --git a/controls/edit.c b/controls/edit.c index 4537c02aca..6b1154c5f9 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -2798,12 +2798,7 @@ static void EDIT_WM_KeyDown(HWND hwnd, WPARAM wParam) return; } - /* FIXME: GetKeyState appears to have its bits reversed */ -#if CorrectGetKeyState if(motionKey && (0x80 & GetKeyState(VK_SHIFT))) { -#else - if(motionKey && (0x01 & GetKeyState(VK_SHIFT))) { -#endif EDIT_ExtendSel(hwnd, es->WndCol, es->WndRow*es->txtht); } else { EDIT_SetAnchor(hwnd, es->CurrLine, es->CurrCol); diff --git a/controls/listbox.c b/controls/listbox.c index 6bba90f193..21f66b4ed4 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -63,6 +63,9 @@ #define LIST_HEAP_SIZE 0x10000 +#define LBMM_EDGE 4 /* distance inside box which is same as moving mouse + outside box, to trigger scrolling of LB */ + static void ListBoxInitialize(LPHEADLIST lphl) { lphl->lpFirst = NULL; @@ -326,7 +329,7 @@ void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls) if (lphl->dwStyle & LBS_OWNERDRAWFIXED) { lphl->StdItemHeight = lpmeasure->itemHeight; - lphl->needMeasure = FALSE; + lpls->mis.itemHeight = lpmeasure->itemHeight; } USER_HEAP_FREE(hTemp); @@ -1036,7 +1039,7 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam)); if ((wParam & MK_LBUTTON) != 0) { y = SHIWORD(lParam); - if (y < 0) { + if (y < LBMM_EDGE) { if (lphl->FirstVisible > 0) { lphl->FirstVisible--; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); @@ -1045,15 +1048,15 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) } } GetClientRect(hwnd, &rect); - if (y >= rect.bottom) { + if (y >= (rect.bottom-LBMM_EDGE)) { if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { lphl->FirstVisible++; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } - } - if ((y > 0) && (y < (rect.bottom - 4))) { + } + if ((y > 0) && (y < (rect.bottom - LBMM_EDGE))) { if ((y < rectsel.top) || (y > rectsel.bottom)) { iRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam)); if (iRet == lphl->ItemFocused || iRet == -1) { @@ -1088,7 +1091,7 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) } return 0; -} + } /*********************************************************************** * LBKeyDown @@ -1281,7 +1284,7 @@ static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) TEXTMETRIC tm; GetTextMetrics( hdc, &tm ); lphl->StdItemHeight = tm.tmHeight; - dprintf_listbox(stddeb,"LBSetFont: new font %d with height %d", + dprintf_listbox(stddeb,"LBSetFont: new font %d with height %d\n", lphl->hFont, lphl->StdItemHeight); ReleaseDC( 0, hdc ); } @@ -1345,7 +1348,7 @@ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) if (i >= lphl->FirstVisible) { height = lpls->mis.itemHeight; - if (top > rect.bottom) { + if (top > (rect.bottom-height+1)) { if (lphl->dwStyle & LBS_MULTICOLUMN) { lphl->ItemsPerColumn = MAX(lphl->ItemsPerColumn, ipc); ipc = 0; diff --git a/controls/menu.c b/controls/menu.c index 0457c11fba..33e58b38d9 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -18,11 +18,11 @@ #include "windows.h" #include "syscolor.h" #include "sysmetrics.h" +#include "win.h" #include "menu.h" #include "module.h" #include "neexe.h" #include "user.h" -#include "win.h" #include "message.h" #include "graphics.h" #include "resource.h" @@ -239,6 +239,9 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, UINT key ) int i; LONG menuchar; + if (!IsMenu( hmenu )) hmenu = GetSystemMenu( hwndOwner, FALSE); + if (!hmenu) return -1; + menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ); lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems ); key = toupper(key); @@ -1624,19 +1627,63 @@ void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ) * * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand(). */ -void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam ) +void MENU_TrackKbdMenuBar( WND* wndPtr, UINT wParam, INT vkey) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr->wIDmenu) return; + UINT uItem = NO_SELECTED_ITEM; + HMENU hTrackMenu; + + /* find window that has a menu + */ + + if( !(wndPtr->dwStyle & WS_CHILD) ) + { + wndPtr = WIN_FindWndPtr( GetActiveWindow() ); + if( !wndPtr ) return; + } + else + while( wndPtr->dwStyle & WS_CHILD && + !(wndPtr->dwStyle & WS_SYSMENU) ) + if( !(wndPtr = wndPtr->parent) ) return; + + if( wndPtr->dwStyle & WS_CHILD || !wndPtr->wIDmenu ) + if( !(wndPtr->dwStyle & WS_SYSMENU) ) + return; + + hTrackMenu = ( IsMenu( wndPtr->wIDmenu ) )? wndPtr->wIDmenu: + wndPtr->hSysMenu; + HideCaret(0); - SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 ); - SendMessage( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 ); - /* Select first selectable item */ - MENU_SelectItem( hwnd, (HMENU)wndPtr->wIDmenu, NO_SELECTED_ITEM ); - MENU_SelectNextItem( hwnd, (HMENU)wndPtr->wIDmenu ); - MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, - 0, 0, hwnd, NULL ); - SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 ); + SendMessage( wndPtr->hwndSelf, WM_ENTERMENULOOP, 0, 0 ); + SendMessage( wndPtr->hwndSelf, WM_INITMENU, wndPtr->wIDmenu, 0 ); + + /* find suitable menu entry + */ + + if( vkey == VK_SPACE ) + uItem = SYSMENU_SELECTED; + else if( vkey ) + { + uItem = MENU_FindItemByKey( wndPtr->hwndSelf, wndPtr->wIDmenu, vkey ); + if( uItem >= 0xFFFE ) + { + if( uItem == 0xFFFF ) + MessageBeep(0); + SendMessage( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 ); + ShowCaret(0); + return; + } + } + + MENU_SelectItem( wndPtr->hwndSelf, hTrackMenu, uItem ); + if( uItem == NO_SELECTED_ITEM ) + MENU_SelectNextItem( wndPtr->hwndSelf, hTrackMenu ); + else + PostMessage( wndPtr->hwndSelf, WM_KEYDOWN, VK_DOWN, 0L ); + + MENU_TrackMenu( hTrackMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, + 0, 0, wndPtr->hwndSelf, NULL ); + + SendMessage( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 ); ShowCaret(0); } @@ -2265,14 +2312,13 @@ HMENU LoadMenu( HINSTANCE instance, SEGPTR name ) dprintf_resource(stddeb,"LoadMenu(%04x,%04x)\n",instance,LOWORD(name)); if (!name) return 0; + + /* check for Win32 module */ + instance = GetExePtr( instance ); + if(((NE_MODULE*)GlobalLock(instance))->flags & NE_FFLAGS_WIN32) + return WIN32_LoadMenuA(instance,PTR_SEG_TO_LIN(name)); - if (!(hRsrc = FindResource( instance, name, RT_MENU ))) { - /* check for Win32 module */ - instance = GetExePtr( instance ); - if(((NE_MODULE*)GlobalLock(instance))->magic == PE_SIGNATURE) - return WIN32_LoadMenuA(instance,PTR_SEG_TO_LIN(name)); - return 0; - } + if (!(hRsrc = FindResource( instance, name, RT_MENU ))) return 0; if (!(handle = LoadResource( instance, hRsrc ))) return 0; hMenu = LoadMenuIndirect( WIN16_LockResource(handle) ); FreeResource( handle ); diff --git a/controls/widgets.c b/controls/widgets.c index 4ae39e3da9..e541835192 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -12,10 +12,8 @@ #include "mdi.h" #include "gdi.h" #include "user.h" -#include "selectors.h" +#include "module.h" #include "stackframe.h" -#include "alias.h" -#include "relay32.h" static WNDCLASS WIDGETS_BuiltinClasses[] = { @@ -67,21 +65,10 @@ BOOL WIDGETS_Init(void) for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++) { - DWORD WineProc,Win16Proc,Win32Proc; - WIN32_builtin *dll; - /* currently, there is no way to get the 'real' pointer at run time */ - WineProc=0; - Win16Proc = (DWORD)GetWndProcEntry16( (char *)class->lpfnWndProc ); - dll = RELAY32_GetBuiltinDLL("WINPROCS32"); - Win32Proc = (DWORD)RELAY32_GetEntryPoint( - dll,(char *)class->lpfnWndProc, 0); - /* Register the alias so we don't pass Win16 pointers to Win32 apps */ - ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc); - strcpy( name, (char *)class->lpszClassName ); class->lpszClassName = MAKE_SEGPTR(name); class->hCursor = LoadCursor( 0, IDC_ARROW ); - class->lpfnWndProc = GetWndProcEntry16( (char *)class->lpfnWndProc ); + class->lpfnWndProc = MODULE_GetWndProcEntry16( (char *)class->lpfnWndProc ); if (!RegisterClass( class )) return FALSE; } return TRUE; diff --git a/if1632/Makefile.in b/if1632/Makefile.in index f896da87f0..311fcab295 100644 --- a/if1632/Makefile.in +++ b/if1632/Makefile.in @@ -2,12 +2,17 @@ TOPSRC = @top_srcdir@ MODULE = if1632 -DLLS16 = \ +DLLS = \ + advapi32.spec \ + comctl32.spec \ + comdlg32.spec \ commdlg.spec \ compobj.spec \ ddeml.spec \ gdi.spec \ + gdi32.spec \ kernel.spec \ + kernel32.spec \ keyboard.spec \ lzexpand.spec \ mmsystem.spec \ @@ -17,51 +22,49 @@ DLLS16 = \ ole2disp.spec \ ole2nls.spec \ ole2prox.spec \ + ole32.spec \ olecli.spec \ olesvr.spec \ shell.spec \ + shell32.spec \ sound.spec \ storage.spec \ stress.spec \ system.spec \ toolhelp.spec \ user.spec \ + user32.spec \ win87em.spec \ winprocs.spec \ - winsock.spec + winprocs32.spec \ + winsock.spec \ + winspool.spec -DLLS32 = advapi32.spec comctl32.spec comdlg32.spec gdi32.spec kernel32.spec \ - ole32.spec shell32.spec user32.spec winprocs32.spec winspool.spec - -SPEC16_FILES = $(DLLS16:.spec=.S) -SPEC32_FILES = $(DLLS32:.spec=.c) +SPEC_FILES = $(DLLS:.spec=.S) C_SRCS = \ - $(SPEC32_FILES) \ callback.c \ dummy.c \ relay.c \ relay32.c ASM_SRCS = \ - $(SPEC16_FILES) \ + $(SPEC_FILES) \ call16.S \ call32.S \ - except.S + except.S \ + stdcall.S .SUFFIXES: .spec .spec.S: - $(BUILD) -spec16 $< > $*.S - -.spec.c: - $(BUILD) -spec32 $< > $*.c + $(BUILD) -spec $< > $*.S all: checkbuild $(MODULE).o @MAKE_RULES@ -$(SPEC16_FILES) $(SPEC32_FILES): $(BUILD) +$(SPEC_FILES): $(BUILD) $(BUILD) checkbuild: cd $(TOPSRC)/tools; $(SUBMAKE) build @@ -69,26 +72,13 @@ $(BUILD) checkbuild: call16.S: $(TOPSRC)/include/callback.h $(BUILD) $(BUILD) -call16 `cat $(TOPSRC)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S -call32.S: $(SPEC16_FILES) - $(BUILD) -call32 `cat $(SPEC16_FILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S +call32.S: $(SPEC_FILES) + $(BUILD) -call32 `cat $(SPEC_FILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S + +stdcall.S: $(SPEC_FILES) + $(BUILD) -stdcall `cat $(SPEC_FILES) | grep Stdcall_ | sed 's/.*Stdcall_\([0-9]*\)/\1/' | sort | uniq` > stdcall.S clean:: - rm -f $(SPEC16_FILES) $(SPEC32_FILES) call32.S call16.S - -# Kludge: don't use optimisation flags to compile these files -advapi32.o: advapi32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o advapi32.o advapi32.c -comdlg32.o: comdlg32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o comdlg32.o comdlg32.c -gdi32.o: gdi32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o gdi32.o gdi32.c -kernel32.o: kernel32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o kernel32.o kernel32.c -shell32.o: shell32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o shell32.o shell32.c -user32.o: user32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o user32.o user32.c -winprocs32.o: winprocs32.c - $(CC) -c -g $(DEFS) $(DIVINCL) $(EXTRA_DEFS) -o winprocs32.o winprocs32.c + rm -f $(SPEC_FILES) call32.S call16.S stdcall.S ### Dependencies: diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec index b5de7d9fa3..28916c429a 100644 --- a/if1632/advapi32.spec +++ b/if1632/advapi32.spec @@ -1,4 +1,5 @@ name advapi32 +type win32 base 1 0000 stub AbortSystemShutdownA @@ -130,37 +131,37 @@ base 1 0126 stdcall RegCloseKey(long) RegCloseKey 0127 stub RegConnectRegistryA 0128 stub RegConnectRegistryW -0129 stub RegCreateKeyA -0130 stdcall RegCreateKeyExA(long ptr long ptr long long ptr ptr ptr) RegCreateKeyEx -0131 stub RegCreateKeyExW -0132 stub RegCreateKeyW -0133 stub RegDeleteKeyA -0134 stub RegDeleteKeyW -0135 stub RegDeleteValueA -0136 stub RegDeleteValueW -0137 stub RegEnumKeyA -0138 stub RegEnumKeyExA -0139 stub RegEnumKeyExW -0140 stub RegEnumKeyW -0141 stub RegEnumValueA -0142 stub RegEnumValueW -0143 stub RegFlushKey +0129 stdcall RegCreateKeyA(long ptr ptr) RegCreateKeyA +0130 stdcall RegCreateKeyExA(long ptr long ptr long long ptr ptr ptr) RegCreateKeyExA +0131 stdcall RegCreateKeyExW(long ptr long ptr long long ptr ptr ptr) RegCreateKeyExW +0132 stdcall RegCreateKeyW(long ptr ptr) RegCreateKeyW +0133 stdcall RegDeleteKeyA(long ptr) RegDeleteKeyA +0134 stdcall RegDeleteKeyW(long ptr) RegDeleteKeyW +0135 stdcall RegDeleteValueA(long ptr) RegDeleteValueA +0136 stdcall RegDeleteValueW(long ptr) RegDeleteValueW +0137 stdcall RegEnumKeyA(long long ptr long) RegEnumKeyA +0138 stdcall RegEnumKeyExA(long long ptr ptr ptr ptr ptr ptr) RegEnumKeyExA +0139 stdcall RegEnumKeyExW(long long ptr ptr ptr ptr ptr ptr) RegEnumKeyExW +0140 stdcall RegEnumKeyW(long long ptr long) RegEnumKeyW +0141 stdcall RegEnumValueA(long long ptr ptr ptr ptr ptr ptr) RegEnumValueA +0142 stdcall RegEnumValueW(long long ptr ptr ptr ptr ptr ptr) RegEnumValueW +0143 stdcall RegFlushKey(long) RegFlushKey 0144 stub RegGetKeySecurity 0145 stub RegLoadKeyA 0146 stub RegLoadKeyW 0147 stub RegNotifyChangeKeyValue -0148 stub RegOpenKeyA -0149 stub RegOpenKeyExA -0150 stub RegOpenKeyExW -0151 stub RegOpenKeyW -0152 stub RegQueryInfoKeyA -0153 stub RegQueryInfoKeyW +0148 stdcall RegOpenKeyA(long ptr ptr) RegOpenKeyA +0149 stdcall RegOpenKeyExA(long ptr long long ptr) RegOpenKeyExA +0150 stdcall RegOpenKeyExW(long ptr long long ptr) RegOpenKeyExW +0151 stdcall RegOpenKeyW(long ptr ptr) RegOpenKeyW +0152 stdcall RegQueryInfoKeyA(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) RegQueryInfoKeyA +0153 stdcall RegQueryInfoKeyW(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) RegQueryInfoKeyW 0154 stub RegQueryMultipleValuesA 0155 stub RegQueryMultipleValuesW -0156 stub RegQueryValueA -0157 stdcall RegQueryValueExA(long ptr long long ptr ptr) RegQueryValueEx -0158 stub RegQueryValueExW -0159 stub RegQueryValueW +0156 stdcall RegQueryValueA(long ptr ptr ptr) RegQueryValueA +0157 stdcall RegQueryValueExA(long ptr ptr ptr ptr ptr) RegQueryValueExA +0158 stdcall RegQueryValueExW(long ptr ptr ptr ptr ptr) RegQueryValueExW +0159 stdcall RegQueryValueW(long ptr ptr ptr) RegQueryValueW 0160 stub RegRemapPreDefKey 0161 stub RegReplaceKeyA 0162 stub RegReplaceKeyW @@ -169,10 +170,10 @@ base 1 0165 stub RegSaveKeyA 0166 stub RegSaveKeyW 0167 stub RegSetKeySecurity -0168 stub RegSetValueA -0169 stdcall RegSetValueExA(long ptr long long ptr long) RegSetValueEx -0170 stub RegSetValueExW -0171 stub RegSetValueW +0168 stdcall RegSetValueA(long ptr long ptr long) RegSetValueA +0169 stdcall RegSetValueExA(long ptr long long ptr long) RegSetValueExA +0170 stdcall RegSetValueExW(long ptr long long ptr long) RegSetValueExW +0171 stdcall RegSetValueW(long ptr long ptr long) RegSetValueW 0172 stub RegUnLoadKeyA 0173 stub RegUnLoadKeyW 0174 stub RegisterEventSourceA diff --git a/if1632/comctl32.spec b/if1632/comctl32.spec index 5967fef274..668d7a9044 100644 --- a/if1632/comctl32.spec +++ b/if1632/comctl32.spec @@ -1,4 +1,5 @@ name comctl32 +type win32 base 2 00 stub MenuHelp diff --git a/if1632/comdlg32.spec b/if1632/comdlg32.spec index 7681ce36eb..8ca5480ed3 100644 --- a/if1632/comdlg32.spec +++ b/if1632/comdlg32.spec @@ -1,4 +1,5 @@ name comdlg32 +type win32 base 1 0000 stub ArrowBtnWndProc diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec index 3f2e25c242..c579065ffa 100644 --- a/if1632/commdlg.spec +++ b/if1632/commdlg.spec @@ -1,4 +1,5 @@ name commdlg +type win16 id 14 1 pascal16 GetOpenFileName(ptr) GetOpenFileName diff --git a/if1632/compobj.spec b/if1632/compobj.spec index c7cffb8bdf..398c68c957 100644 --- a/if1632/compobj.spec +++ b/if1632/compobj.spec @@ -1,4 +1,5 @@ name compobj +type win16 id 22 1 pascal CoBuildVersion() CoBuildVersion diff --git a/if1632/ddeml.spec b/if1632/ddeml.spec index d585ef523e..0a03761143 100644 --- a/if1632/ddeml.spec +++ b/if1632/ddeml.spec @@ -1,4 +1,5 @@ name ddeml +type win16 id 25 2 stub DdeInitialize #(ptr segptr long long) DdeInitialize diff --git a/if1632/gdi.spec b/if1632/gdi.spec index a01f1b1222..08d7d6a2f6 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -1,4 +1,5 @@ name gdi +type win16 id 3 1 pascal SetBkColor(word long) SetBkColor diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec index 299f8333a0..dae9cc111c 100644 --- a/if1632/gdi32.spec +++ b/if1632/gdi32.spec @@ -1,4 +1,5 @@ name gdi32 +type win32 base 1 0000 stub AbortDoc diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 7d874edf94..c2cabe6678 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -1,4 +1,5 @@ name kernel +type win16 id 1 1 stub FatalExit @@ -208,15 +209,15 @@ id 1 216 pascal RegEnumKey(long long ptr long) RegEnumKey 217 pascal RegOpenKey(long ptr ptr) RegOpenKey 218 pascal RegCreateKey(long ptr ptr) RegCreateKey -219 stub RegDeleteValue +219 pascal RegDeleteKey(long ptr) RegDeleteKey 220 pascal RegCloseKey(long) RegCloseKey 221 pascal RegSetValue(long ptr long ptr long) RegSetValue -222 stub RegDeleteValue -223 stub RegEnumValue +222 pascal RegDeleteValue(long ptr) RegDeleteValue +223 pascal RegEnumValue(long long ptr ptr ptr ptr ptr ptr) RegEnumValue 224 pascal RegQueryValue(long ptr ptr ptr) RegQueryValue -225 stub RegQueryValueEx -226 stub RegSetValueEx -227 stub RegFlushKey +225 pascal RegQueryValueEx(long ptr ptr ptr ptr ptr) RegQueryValueEx +226 pascal RegSetValueEx(long ptr long long ptr long) RegSetValueEx +227 pascal RegFlushKey(long) RegFlushKey #228 K228 #229 K229 230 stub GlobalSmartPageLock diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec index 3388430dc6..f205374528 100644 --- a/if1632/kernel32.spec +++ b/if1632/kernel32.spec @@ -1,4 +1,5 @@ name kernel32 +type win32 base 1 0000 stub AddAtomA diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec index 714bd3c037..582036325c 100644 --- a/if1632/keyboard.spec +++ b/if1632/keyboard.spec @@ -1,4 +1,5 @@ name keyboard +type win16 id 7 #1 pascal Inquire diff --git a/if1632/lzexpand.spec b/if1632/lzexpand.spec index 9f2e38d58b..3e6b2c9e46 100644 --- a/if1632/lzexpand.spec +++ b/if1632/lzexpand.spec @@ -1,4 +1,5 @@ name lzexpand +type win16 id 26 1 pascal LZCopy(word word) LZCopy diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec index 14171d4924..cb282047e8 100644 --- a/if1632/mmsystem.spec +++ b/if1632/mmsystem.spec @@ -1,4 +1,5 @@ name mmsystem +type win16 id 10 #1 pascal MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP diff --git a/if1632/mouse.spec b/if1632/mouse.spec index 0c04a8d1f0..fe8599f6e1 100644 --- a/if1632/mouse.spec +++ b/if1632/mouse.spec @@ -1,4 +1,5 @@ name mouse +type win16 id 13 1 stub INQUIRE diff --git a/if1632/ole2.spec b/if1632/ole2.spec index c3caa82534..f7c8ad2c8f 100644 --- a/if1632/ole2.spec +++ b/if1632/ole2.spec @@ -1,4 +1,5 @@ name OLE2 +type win16 id 15 1 pascal OleBuildVersion() OleBuildVersion diff --git a/if1632/ole2conv.spec b/if1632/ole2conv.spec index d2414bd8a2..39808a87a7 100644 --- a/if1632/ole2conv.spec +++ b/if1632/ole2conv.spec @@ -1,4 +1,5 @@ name ole2conv +type win16 id 16 1 stub GETFILTERINFO diff --git a/if1632/ole2disp.spec b/if1632/ole2disp.spec index e8f34bf510..1364f5a2d4 100644 --- a/if1632/ole2disp.spec +++ b/if1632/ole2disp.spec @@ -1,4 +1,5 @@ name ole2disp +type win16 id 17 1 stub DLLGETCLASSOBJECT diff --git a/if1632/ole2nls.spec b/if1632/ole2nls.spec index 9e70445c9e..57b136a4fa 100644 --- a/if1632/ole2nls.spec +++ b/if1632/ole2nls.spec @@ -1,4 +1,5 @@ name ole2nls +type win16 id 18 1 pascal GetUserDefaultLCID() GetUserDefaultLCID diff --git a/if1632/ole2prox.spec b/if1632/ole2prox.spec index 1d3868a759..e2822cbddf 100644 --- a/if1632/ole2prox.spec +++ b/if1632/ole2prox.spec @@ -1,4 +1,5 @@ name ole2prox +type win16 id 19 1 stub DLLGETCLASSOBJECT diff --git a/if1632/ole32.spec b/if1632/ole32.spec index f9c6dd2eea..cf9311712f 100644 --- a/if1632/ole32.spec +++ b/if1632/ole32.spec @@ -1,4 +1,5 @@ name ole32 +type win32 base 1 0 stub BindMoniker diff --git a/if1632/olecli.spec b/if1632/olecli.spec index 03ef5ca50a..9376d6972a 100644 --- a/if1632/olecli.spec +++ b/if1632/olecli.spec @@ -1,4 +1,5 @@ name olecli +type win16 id 20 #1 WEP diff --git a/if1632/olesvr.spec b/if1632/olesvr.spec index ca3f1bdeb4..a79115d08b 100644 --- a/if1632/olesvr.spec +++ b/if1632/olesvr.spec @@ -1,4 +1,5 @@ name olesvr +type win16 id 21 #1 WEP diff --git a/if1632/relay.c b/if1632/relay.c index b0f3d9bbba..c3960ba587 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -19,45 +19,41 @@ dprintf_relay #endif -#define DLL_ENTRY(name) \ +#define DLL_ENTRY(name,flags) \ { #name, name##_Code_Start, name##_Data_Start, \ - name##_Module_Start, name##_Module_End, TRUE, 0 } -#define DLL_ENTRY_NOTUSED(name) \ - { #name, name##_Code_Start, name##_Data_Start, \ - name##_Module_Start, name##_Module_End, FALSE, 0 } + name##_Module_Start, name##_Module_End, (flags) } -struct dll_table_s dll_builtin_table[N_BUILTINS] = +BUILTIN_DLL dll_builtin_table[] = { - DLL_ENTRY(KERNEL), - DLL_ENTRY(USER), - DLL_ENTRY(GDI), - DLL_ENTRY_NOTUSED(WIN87EM), - DLL_ENTRY_NOTUSED(SHELL), - DLL_ENTRY(SOUND), - DLL_ENTRY(KEYBOARD), - DLL_ENTRY(WINSOCK), - DLL_ENTRY(STRESS), - DLL_ENTRY(MMSYSTEM), - DLL_ENTRY(SYSTEM), - DLL_ENTRY(TOOLHELP), - DLL_ENTRY(MOUSE), - DLL_ENTRY_NOTUSED(COMMDLG), - DLL_ENTRY_NOTUSED(OLE2), - DLL_ENTRY_NOTUSED(OLE2CONV), - DLL_ENTRY_NOTUSED(OLE2DISP), - DLL_ENTRY_NOTUSED(OLE2NLS), - DLL_ENTRY_NOTUSED(OLE2PROX), - DLL_ENTRY_NOTUSED(OLECLI), - DLL_ENTRY_NOTUSED(OLESVR), - DLL_ENTRY_NOTUSED(COMPOBJ), - DLL_ENTRY_NOTUSED(STORAGE), - DLL_ENTRY(WINPROCS), - DLL_ENTRY_NOTUSED(DDEML), - DLL_ENTRY(LZEXPAND) + DLL_ENTRY( KERNEL, 0), + DLL_ENTRY( USER, 0), + DLL_ENTRY( GDI, 0), + DLL_ENTRY( WIN87EM, DLL_FLAG_NOT_USED), + DLL_ENTRY( SHELL, 0), + DLL_ENTRY( SOUND, 0), + DLL_ENTRY( KEYBOARD, 0), + DLL_ENTRY( WINSOCK, 0), + DLL_ENTRY( STRESS, 0), + DLL_ENTRY( MMSYSTEM, 0), + DLL_ENTRY( SYSTEM, 0), + DLL_ENTRY( TOOLHELP, 0), + DLL_ENTRY( MOUSE, 0), + DLL_ENTRY( COMMDLG, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLE2, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLE2CONV, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLE2DISP, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLE2NLS, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLE2PROX, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLECLI, DLL_FLAG_NOT_USED), + DLL_ENTRY( OLESVR, DLL_FLAG_NOT_USED), + DLL_ENTRY( COMPOBJ, DLL_FLAG_NOT_USED), + DLL_ENTRY( STORAGE, DLL_FLAG_NOT_USED), + DLL_ENTRY( WINPROCS, 0), + DLL_ENTRY( DDEML, DLL_FLAG_NOT_USED), + DLL_ENTRY( LZEXPAND, 0), + { NULL, } /* Last entry */ }; -/* don't forget to increase N_BUILTINS in dlls.h if you add a dll */ - /* Saved 16-bit stack */ WORD IF1632_Saved16_ss = 0; WORD IF1632_Saved16_sp = 0; @@ -112,8 +108,8 @@ void RELAY_DebugCall32( int func_type, char *args, frame = CURRENT_STACK16; table = &dll_builtin_table[frame->dll_id-1]; name = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number ); - printf( "Call %s.%d: %*.*s(", - table->name, frame->ordinal_number, *name, *name, name + 1 ); + printf( "Call %s.%d: %.*s(", + table->name, frame->ordinal_number, *name, name + 1 ); args16 = (char *)frame->args; for (i = 0; i < strlen(args); i++) @@ -184,8 +180,8 @@ void RELAY_DebugReturn( int func_type, int ret_val, int args32 ) frame = CURRENT_STACK16; table = &dll_builtin_table[frame->dll_id-1]; name = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number ); - printf( "Ret %s.%d: %*.*s() ", - table->name, frame->ordinal_number, *name, *name, name + 1 ); + printf( "Ret %s.%d: %.*s() ", + table->name, frame->ordinal_number, *name, name + 1 ); switch(func_type) { case 0: /* long */ @@ -212,19 +208,34 @@ void RELAY_DebugReturn( int func_type, int ret_val, int args32 ) /*********************************************************************** - * RELAY_Unimplemented + * RELAY_Unimplemented16 * - * This function is called for unimplemented entry points (declared + * This function is called for unimplemented 16-bit entry points (declared * as 'stub' in the spec file). */ -void RELAY_Unimplemented(void) +void RELAY_Unimplemented16(void) { STACK16FRAME *frame = CURRENT_STACK16; struct dll_table_s *table = &dll_builtin_table[frame->dll_id-1]; char *name = MODULE_GetEntryPointName( table->hModule, frame->ordinal_number ); - fprintf( stderr, "No handler for routine %s.%d (%*.*s)\n", - table->name, frame->ordinal_number, *name, *name, name + 1 ); + fprintf( stderr, "No handler for routine %s.%d (%.*s)\n", + table->name, frame->ordinal_number, *name, name + 1 ); + exit(1); +} + + +/*********************************************************************** + * RELAY_Unimplemented32 + * + * This function is called for unimplemented 32-bit entry points (declared + * as 'stub' in the spec file). + * (The args are the same than for RELAY_DebugStdcall). + */ +void RELAY_Unimplemented32( int nb_args, void *entry_point, + const char *func_name ) +{ + fprintf( stderr, "No handler for Win32 routine %s\n", func_name ); exit(1); } @@ -250,3 +261,33 @@ void RELAY_DebugCall16( int* stack, int nbargs ) while (nbargs--) printf( ",0x%04x", *stack++ ); printf( ")\n" ); } + + +/*********************************************************************** + * RELAY_DebugStdcall + */ +void RELAY_DebugStdcall( int nb_args, void *entry_point, const char *func_name, + int ebp, int ret_addr, int arg1 ) +{ + int *parg; + if (!debugging_relay) return; + printf( "Call %s(", func_name ); + for (parg = &arg1; nb_args; parg++, nb_args--) + { + printf( "%08x", *parg ); + if (nb_args > 1) printf( "," ); + } + printf( ") ret=%08x\n", ret_addr ); +} + + +/*********************************************************************** + * RELAY_DebugStdcallRet + */ +void RELAY_DebugStdcallRet( int ret_val, void *entry_point, + const char *func_name, int ebp, int ret_addr ) +{ + if (!debugging_relay) return; + printf( "Ret %s() retval=0x%08x ret=%08x\n", + func_name, ret_val, ret_addr ); +} diff --git a/if1632/relay32.c b/if1632/relay32.c index 4ec11047f6..418f1cccf2 100644 --- a/if1632/relay32.c +++ b/if1632/relay32.c @@ -24,37 +24,37 @@ #include "stddebug.h" #include "debug.h" -WIN32_builtin *WIN32_builtin_list; +#define DLL_ENTRY(name) \ + { #name, (WIN32_function *)name##_Module_Start, \ + (WIN32_function *)name##_Module_End, (int *)name##_Data_Start, NULL } -/* Functions are in generated code */ -void ADVAPI32_Init(); -void COMCTL32_Init(); -void COMDLG32_Init(); -void OLE32_Init(); -void GDI32_Init(); -void KERNEL32_Init(); -void SHELL32_Init(); -void USER32_Init(); -void WINPROCS32_Init(); -void WINSPOOL_Init(); +static WIN32_builtin WIN32_builtin_list[] = +{ + DLL_ENTRY(ADVAPI32), + DLL_ENTRY(COMCTL32), + DLL_ENTRY(COMDLG32), + DLL_ENTRY(OLE32), + DLL_ENTRY(GDI32), + DLL_ENTRY(KERNEL32), + DLL_ENTRY(SHELL32), + DLL_ENTRY(USER32), + DLL_ENTRY(WINPROCS32), + DLL_ENTRY(WINSPOOL) +}; + +#define NB_DLLS (sizeof(WIN32_builtin_list)/sizeof(WIN32_builtin_list[0])) + +static void RELAY32_MakeFakeModule(WIN32_builtin*dll); int RELAY32_Init(void) { -#ifndef WINELIB - /* Add a call for each DLL */ - ADVAPI32_Init(); - COMCTL32_Init(); - COMDLG32_Init(); - GDI32_Init(); - KERNEL32_Init(); - OLE32_Init(); - SHELL32_Init(); - USER32_Init(); - WINPROCS32_Init(); - WINSPOOL_Init(); -#endif - /* Why should it fail, anyways? */ - return 1; + int i; + + for (i = 0; i < NB_DLLS; i++) + RELAY32_MakeFakeModule( &WIN32_builtin_list[i] ); + + /* Why should it fail, anyways? */ + return 1; } WIN32_builtin *RELAY32_GetBuiltinDLL(char *name) @@ -62,11 +62,11 @@ WIN32_builtin *RELAY32_GetBuiltinDLL(char *name) WIN32_builtin *it; size_t len; char *cp; + int i; len = (cp=strchr(name,'.')) ? (cp-name) : strlen(name); - for(it=WIN32_builtin_list;it;it=it->next) - if(lstrncmpi(name,it->name,len)==0) - return it; + for(i = NB_DLLS, it = WIN32_builtin_list; (i > 0); i--, it++) + if (!lstrncmpi(name,it->name,len)) return it; return NULL; } @@ -85,30 +85,32 @@ void RELAY32_Unimplemented(char *dll, int item) void *RELAY32_GetEntryPoint(WIN32_builtin *dll, char *item, int hint) { - int i; + int i, size; dprintf_module(stddeb, "Looking for %s in %s, hint %x\n", item ? item: "(no name)", dll->name, hint); if(!dll) return 0; + size = (int)(dll->last_func - dll->functions); + /* import by ordinal */ if(!item){ - if(hint && hintsize) - return dll->functions[hint-dll->base].definition; + if(hint && hint < size) + return dll->functions[hint - *dll->base].definition; return 0; } /* hint is correct */ - if(hint && hintsize && + if(hint && hint < size && dll->functions[hint].name && strcmp(item,dll->functions[hint].name)==0) return dll->functions[hint].definition; /* hint is incorrect, search for name */ - for(i=0;isize;i++) + for(i=0;i < size;i++) if (dll->functions[i].name && !strcmp(item,dll->functions[i].name)) return dll->functions[i].definition; /* function at hint has no name (unimplemented) */ - if(hint && hintsize && !dll->functions[hint].name) + if(hint && hint < size && !dll->functions[hint].name) { dll->functions[hint].name=xstrdup(item); dprintf_module(stddeb, "Returning unimplemented function %s.%d\n", @@ -118,11 +120,6 @@ void *RELAY32_GetEntryPoint(WIN32_builtin *dll, char *item, int hint) return 0; } -void RELAY32_DebugEnter(char *dll,char *name) -{ - dprintf_relay(stddeb, "Entering %s.%s\n",dll,name); -} - LONG RELAY32_CallWindowProc( WNDPROC func, int hwnd, int message, int wParam, int lParam ) { @@ -201,7 +198,7 @@ LONG RELAY32_CallWindowProcConvStruct( WNDPROC func, int hwnd, int message, return RELAY32_CallWindowProc(func,hwnd,message,wParam,(int)lParam); } -void RELAY32_MakeFakeModule(WIN32_builtin*dll) +static void RELAY32_MakeFakeModule(WIN32_builtin*dll) { NE_MODULE *pModule; struct w_files *wpnt; @@ -227,10 +224,10 @@ void RELAY32_MakeFakeModule(WIN32_builtin*dll) FarSetOwner( hModule, hModule ); pModule = (NE_MODULE*)GlobalLock(hModule); /* Set all used entries */ - pModule->magic=PE_SIGNATURE; + pModule->magic=NE_SIGNATURE; pModule->count=1; pModule->next=0; - pModule->flags=0; + pModule->flags=NE_FFLAGS_WIN32; pModule->dgroup=0; pModule->ss=0; pModule->cs=0; diff --git a/if1632/shell.spec b/if1632/shell.spec index 8f01e02a5a..f7b2beaae2 100644 --- a/if1632/shell.spec +++ b/if1632/shell.spec @@ -1,11 +1,7 @@ name shell +type win16 id 5 -# -# WARNING ! These functions are not documented, so I didn't look for -# proper parameters. It's just to have stub for PROGMAN.EXE ... -# - 1 pascal RegOpenKey(long ptr ptr) RegOpenKey 2 pascal RegCreateKey(long ptr ptr) RegCreateKey 3 pascal RegCloseKey(long) RegCloseKey @@ -31,12 +27,5 @@ id 5 # 8 7 0000 WEP exported, shared data #100 4 0550 HERETHARBETYGARS exported, shared data -# 38 5 0000 FINDENVIRONMENTSTRING exported, shared data -# 37 5 00ae DOENVIRONMENTSUBST exported, shared data -# 20 4 110a SHELLEXECUTE exported, shared data #101 8 010e FINDEXEDLGPROC exported, shared data -# 39 10 026e INTERNALEXTRACTICON exported, shared data # 32 9 0829 WCI exported, shared data -# 36 10 08dc EXTRACTASSOCIATEDICON exported, shared data - - diff --git a/if1632/shell32.spec b/if1632/shell32.spec index 1e191e2fee..1e0a54bad5 100644 --- a/if1632/shell32.spec +++ b/if1632/shell32.spec @@ -1,4 +1,5 @@ name shell32 +type win32 base 1 0000 stub CheckEscapesA diff --git a/if1632/sound.spec b/if1632/sound.spec index 2191fddf66..23b656ff2a 100644 --- a/if1632/sound.spec +++ b/if1632/sound.spec @@ -1,4 +1,5 @@ name sound +type win16 id 6 1 pascal16 OpenSound() OpenSound diff --git a/if1632/storage.spec b/if1632/storage.spec index 08efdc3fe7..2c03b1e088 100644 --- a/if1632/storage.spec +++ b/if1632/storage.spec @@ -1,4 +1,5 @@ name storage +type win16 id 23 1 stub StgCreateDocFile diff --git a/if1632/stress.spec b/if1632/stress.spec index 738de00254..69c83097c5 100644 --- a/if1632/stress.spec +++ b/if1632/stress.spec @@ -1,6 +1,7 @@ # summary: resource modification dll # name stress +type win16 id 9 2 pascal allocmem(long) AllocMem diff --git a/if1632/system.spec b/if1632/system.spec index de7816eb8f..975364cb88 100644 --- a/if1632/system.spec +++ b/if1632/system.spec @@ -1,4 +1,5 @@ name system +type win16 id 11 1 stub InquireSystem diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec index 1c590d4cf5..908505373e 100644 --- a/if1632/toolhelp.spec +++ b/if1632/toolhelp.spec @@ -1,4 +1,5 @@ name toolhelp +type win16 id 12 50 pascal16 GlobalHandleToSel(word) GlobalHandleToSel diff --git a/if1632/user.spec b/if1632/user.spec index fcc0b1baaf..721fde088b 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -1,4 +1,5 @@ name user +type win16 id 2 1 pascal16 MessageBox(word ptr ptr word) MessageBox diff --git a/if1632/user32.spec b/if1632/user32.spec index 9934c77d70..13e7ab741f 100644 --- a/if1632/user32.spec +++ b/if1632/user32.spec @@ -1,4 +1,5 @@ name user32 +type win32 base 1 0000 stub ActivateKeyboardLayout @@ -592,7 +593,7 @@ base 1 0581 stub WindowFromPoint 0582 stub keybd_event 0583 stub mouse_event -0584 cdecl wsprintfA(ptr ptr ...) vsprintf +0584 stdcall wsprintfA() USER32_wsprintfA 0585 stub wsprintfW 0586 stub wvsprintfA 0587 stub wvsprintfW diff --git a/if1632/win87em.spec b/if1632/win87em.spec index 71759fad3b..7cee1985e3 100644 --- a/if1632/win87em.spec +++ b/if1632/win87em.spec @@ -1,4 +1,5 @@ name win87em +type win16 id 4 1 register _fpMath() WIN87_fpmath diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec index e564fa53bc..62274e86b9 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec @@ -1,4 +1,5 @@ name winprocs +type win16 id 24 1 pascal ButtonWndProc(word word word long) ButtonWndProc diff --git a/if1632/winprocs32.spec b/if1632/winprocs32.spec index 6bb7b0b34d..d40dafad82 100644 --- a/if1632/winprocs32.spec +++ b/if1632/winprocs32.spec @@ -1,4 +1,5 @@ name winprocs32 +type win32 1 stdcall ButtonWndProc(long long long long) ButtonWndProc32 2 stdcall StaticWndProc(long long long long) StaticWndProc32 diff --git a/if1632/winsock.spec b/if1632/winsock.spec index 813f364019..52975071be 100644 --- a/if1632/winsock.spec +++ b/if1632/winsock.spec @@ -4,6 +4,7 @@ # Summary: Module definition file for Windows Sockets DLL. # name winsock +type win16 id 8 1 pascal16 accept(word ptr ptr) WINSOCK_accept diff --git a/if1632/winspool.spec b/if1632/winspool.spec index d3ac3157a6..12e16f661e 100644 --- a/if1632/winspool.spec +++ b/if1632/winspool.spec @@ -1,4 +1,5 @@ name winspool +type win32 base 100 001 stub ADVANCEDSETUPDIALOG diff --git a/include/advapi32.h b/include/advapi32.h index 634c3f4373..d4531ad3b8 100644 --- a/include/advapi32.h +++ b/include/advapi32.h @@ -2,30 +2,7 @@ #define __WINE_ADVAPI32_H #include "shell.h" #include "kernel32.h" -#define REGSAM long -BOOL WINAPI GetUserNameA (char * lpBuffer, DWORD *nSize); -WINAPI LONG RegCreateKeyEx(HKEY key, - const char *subkey, - long dontuse, - const char *keyclass, - DWORD options, - REGSAM sam, - SECURITY_ATTRIBUTES *atts, - HKEY *res, - DWORD *disp); -WINAPI LONG RegSetValueExA (HKEY key, - const char *name, - DWORD dontuse, - DWORD type, - const void* data, - DWORD len - ); -WINAPI LONG RegQueryValueExA(HKEY key, - const char *subkey, - DWORD dontuse, - DWORD *type, - void *ptr, - DWORD *len); +BOOL WINAPI GetUserNameA (char * lpBuffer, DWORD *nSize); #endif /* __WINE_ADVAPI32_H */ diff --git a/include/alias.h b/include/alias.h index 26daa04b34..c6d93e355a 100644 --- a/include/alias.h +++ b/include/alias.h @@ -5,10 +5,16 @@ * */ -typedef struct _FUNCTIONALIAS{ - DWORD wine; - DWORD win16; - DWORD win32; +#ifndef __WINE_ALIAS_H +#define __WINE_ALIAS_H + +#include "wintypes.h" + +typedef struct +{ + DWORD wine; + DWORD win16; + DWORD win32; } FUNCTIONALIAS; extern int ALIAS_UseAliases; @@ -18,6 +24,8 @@ typedef struct _ALIASHASH{ int recno; } ALIASHASH; -void ALIAS_RegisterAlias(DWORD,DWORD,DWORD); -FUNCTIONALIAS* ALIAS_LookupAlias(DWORD); +extern BOOL ALIAS_Init(void); +extern void ALIAS_RegisterAlias( DWORD Wine, DWORD Win16Proc, DWORD Win32Proc); +extern FUNCTIONALIAS* ALIAS_LookupAlias(DWORD); +#endif /* __WINE_ALIAS_H */ diff --git a/include/bitmaps/ocr_ibeam b/include/bitmaps/ocr_ibeam index e372a1eab6..5f77564b15 100644 --- a/include/bitmaps/ocr_ibeam +++ b/include/bitmaps/ocr_ibeam @@ -1,6 +1,6 @@ /* XPM */ static char * ocr_ibeam[] = { -"32 32 2 1 3 8", +"32 32 2 1 0 8", " s black c black", ". s None c None", " . .........................", diff --git a/include/dlls.h b/include/dlls.h index 00b5980958..2e5bcbcadc 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -1,34 +1,35 @@ -/* $Id: dlls.h,v 1.2 1993/07/04 04:04:21 root Exp root $ - */ /* * Copyright Robert J. Amstadt, 1993 */ -#ifndef DLLS_H -#define DLLS_H +#ifndef __WINE_DLLS_H +#define __WINE_DLLS_H #include "wintypes.h" -#define MAX_NAME_LENGTH 64 - -struct dll_table_s +typedef struct dll_table_s { - char * name; /* DLL name */ - BYTE * code_start; /* 32-bit address of DLL code */ - BYTE * data_start; /* 32-bit address of DLL data */ - BYTE * module_start; /* 32-bit address of the module data */ - BYTE * module_end; - BOOL used; /* use MS provided if FALSE */ - HMODULE hModule; /* module created for this DLL */ -}; + char *name; /* DLL name */ + const BYTE *code_start; /* 32-bit address of DLL code */ + const BYTE *data_start; /* 32-bit address of DLL data */ + BYTE *module_start; /* 32-bit address of the module data */ + BYTE *module_end; + int flags; /* flags (see below) */ + HMODULE hModule; /* module created for this DLL */ +} BUILTIN_DLL; + +/* DLL flags */ +#define DLL_FLAG_NOT_USED 1 /* Use original Windows DLL if possible */ +#define DLL_FLAG_WIN32 2 /* DLL is a Win32 DLL */ #define DECLARE_DLL(name) \ -extern BYTE name##_Code_Start[]; \ -extern BYTE name##_Data_Start[]; \ +extern const BYTE name##_Code_Start[]; \ +extern const BYTE name##_Data_Start[]; \ extern BYTE name##_Module_Start[]; \ extern BYTE name##_Module_End[]; +/* 16-bit DLLs */ DECLARE_DLL(KERNEL) DECLARE_DLL(USER) DECLARE_DLL(GDI) @@ -56,8 +57,19 @@ DECLARE_DLL(WINPROCS) DECLARE_DLL(DDEML) DECLARE_DLL(LZEXPAND) -#define N_BUILTINS 26 +/* 32-bit DLLs */ -extern struct dll_table_s dll_builtin_table[]; +DECLARE_DLL(ADVAPI32) +DECLARE_DLL(COMCTL32) +DECLARE_DLL(COMDLG32) +DECLARE_DLL(OLE32) +DECLARE_DLL(GDI32) +DECLARE_DLL(KERNEL32) +DECLARE_DLL(SHELL32) +DECLARE_DLL(USER32) +DECLARE_DLL(WINPROCS32) +DECLARE_DLL(WINSPOOL) -#endif /* DLLS_H */ +extern BUILTIN_DLL dll_builtin_table[]; + +#endif /* __WINE_DLLS_H */ diff --git a/include/kernel32.h b/include/kernel32.h index 1b0febc14e..2a078d3a9c 100644 --- a/include/kernel32.h +++ b/include/kernel32.h @@ -92,20 +92,6 @@ typedef struct { #define STD_OUTPUT_HANDLE ((DWORD) -11) #define STD_ERROR_HANDLE ((DWORD) -12) -/* The security attributes structure - */ -typedef struct { - DWORD nLength; - void *lpSecurityDescriptor; - BOOL bInheritHandle; -} SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; - -typedef struct -{ - int dwLowDateTime; - int dwHighDateTime; -} FILETIME; - typedef struct { int dwFileAttributes; diff --git a/include/menu.h b/include/menu.h index 41f2047f77..32c4ff77b4 100644 --- a/include/menu.h +++ b/include/menu.h @@ -12,7 +12,7 @@ extern BOOL MENU_Init(void); extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, int orgX, int orgY ); /* menu.c */ extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ); /* menu.c */ -extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam ); /* menu.c */ +extern void MENU_TrackKbdMenuBar( WND*, UINT wParam, INT vkey); /* menu.c */ extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, BOOL suppress_draw ); /* menu.c */ extern LRESULT PopupMenuWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam ); diff --git a/include/miscemu.h b/include/miscemu.h index af6b061264..0ee35f6cab 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -12,7 +12,7 @@ /* miscemu/dosmem.c */ extern BOOL DOSMEM_Init(void); -extern void DOSMEM_Alarm(void); +extern void DOSMEM_Tick(void); extern void DOSMEM_FillBiosSegment(void); extern HANDLE DOSMEM_BiosSeg; diff --git a/include/module.h b/include/module.h index c19f764aa4..bc23e1c281 100644 --- a/include/module.h +++ b/include/module.h @@ -105,10 +105,12 @@ extern BOOL MODULE_Init(void); extern int MODULE_OpenFile( HMODULE hModule ); extern LPSTR MODULE_GetModuleName( HMODULE hModule ); extern void MODULE_RegisterModule( HMODULE hModule ); -extern WORD MODULE_GetOrdinal( HMODULE hModule, char *name ); +extern WORD MODULE_GetOrdinal( HMODULE hModule, const char *name ); extern SEGPTR MODULE_GetEntryPoint( HMODULE hModule, WORD ordinal ); extern BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset ); extern LPSTR MODULE_GetEntryPointName( HMODULE hModule, WORD ordinal ); +extern FARPROC MODULE_GetWndProcEntry16( const char *name ); +extern FARPROC MODULE_GetWndProcEntry32( const char *name ); extern BOOL NE_LoadSegment( HMODULE hModule, WORD segnum ); extern void NE_FixupPrologs( HMODULE hModule ); diff --git a/include/neexe.h b/include/neexe.h index e8c460cc8d..096050b291 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -26,38 +26,38 @@ struct mz_header_s */ struct ne_header_s { - WORD ne_magic; /* NE signature 'NE' */ - BYTE linker_version; /* Linker version number */ - BYTE linker_revision; /* Linker revision number */ - WORD entry_tab_offset; /* Offset to entry table relative to NE */ - WORD entry_tab_length; /* Length of entry table in bytes */ - DWORD reserved1; /* Reserved by Microsoft */ - WORD format_flags; /* Flags about segments in this file */ - WORD auto_data_seg; /* Automatic data segment number */ - WORD local_heap_length; /* Initial size of local heap */ - WORD stack_length; /* Initial size of stack */ - WORD ip; /* Initial IP */ - WORD cs; /* Initial CS */ - WORD sp; /* Initial SP */ - WORD ss; /* Initial SS */ - WORD n_segment_tab; /* # of entries in segment table */ - WORD n_mod_ref_tab; /* # of entries in module reference tab.*/ - WORD nrname_tab_length; /* Length of nonresident-name table */ - WORD segment_tab_offset; /* Offset to segment table */ - WORD resource_tab_offset;/* Offset to resource table */ - WORD rname_tab_offset; /* Offset to resident-name table */ - WORD moduleref_tab_offset;/* Offset to module reference table */ - WORD iname_tab_offset; /* Offset to imported name table */ - DWORD nrname_tab_offset; /* Offset to nonresident-name table */ - WORD n_mov_entry_points; /* # of movable entry points */ - WORD align_shift_count; /* Logical sector alignment shift count */ - WORD n_resource_seg; /* # of resource segments */ - BYTE operating_system; /* Flags indicating target OS */ - BYTE additional_flags; /* Additional information flags */ - WORD fastload_offset; /* Offset to fast load area */ - WORD fastload_length; /* Length of fast load area */ - WORD reserved2; /* Reserved by Microsoft */ - WORD expect_version; /* Expected Windows version number */ + WORD ne_magic; /* 00 NE signature 'NE' */ + BYTE linker_version; /* 02 Linker version number */ + BYTE linker_revision; /* 03 Linker revision number */ + WORD entry_tab_offset; /* 04 Offset to entry table relative to NE */ + WORD entry_tab_length; /* 06 Length of entry table in bytes */ + DWORD reserved1; /* 08 Reserved by Microsoft */ + WORD format_flags; /* 0c Flags about segments in this file */ + WORD auto_data_seg; /* 0e Automatic data segment number */ + WORD local_heap_length; /* 10 Initial size of local heap */ + WORD stack_length; /* 12 Initial size of stack */ + WORD ip; /* 14 Initial IP */ + WORD cs; /* 16 Initial CS */ + WORD sp; /* 18 Initial SP */ + WORD ss; /* 1a Initial SS */ + WORD n_segment_tab; /* 1c # of entries in segment table */ + WORD n_mod_ref_tab; /* 1e # of entries in module reference tab. */ + WORD nrname_tab_length; /* 20 Length of nonresident-name table */ + WORD segment_tab_offset; /* 22 Offset to segment table */ + WORD resource_tab_offset; /* 24 Offset to resource table */ + WORD rname_tab_offset; /* 26 Offset to resident-name table */ + WORD moduleref_tab_offset; /* 28 Offset to module reference table */ + WORD iname_tab_offset; /* 2a Offset to imported name table */ + DWORD nrname_tab_offset; /* 2c Offset to nonresident-name table */ + WORD n_mov_entry_points; /* 30 # of movable entry points */ + WORD align_shift_count; /* 32 Logical sector alignment shift count */ + WORD n_resource_seg; /* 34 # of resource segments */ + BYTE operating_system; /* 36 Flags indicating target OS */ + BYTE additional_flags; /* 37 Additional information flags */ + WORD fastload_offset; /* 38 Offset to fast load area */ + WORD fastload_length; /* 3a Length of fast load area */ + WORD reserved2; /* 3c Reserved by Microsoft */ + WORD expect_version; /* 3e Expected Windows version number */ }; #define NE_SIGNATURE ('N' | ('E' << 8)) @@ -68,9 +68,11 @@ struct ne_header_s */ #define NE_FFLAGS_SINGLEDATA 0x0001 #define NE_FFLAGS_MULTIPLEDATA 0x0002 -#define NE_FFLAGS_BUILTIN 0x0010 /* Wine built-in module */ +#define NE_FFLAGS_WIN32 0x0010 +#define NE_FFLAGS_BUILTIN 0x0020 /* Wine built-in module */ #define NE_FFLAGS_SELFLOAD 0x0800 #define NE_FFLAGS_LINKERROR 0x2000 +#define NE_FFLAGS_CALLWEP 0x4000 #define NE_FFLAGS_LIBMODULE 0x8000 /* diff --git a/include/nonclient.h b/include/nonclient.h index d2ca8abdfd..c890201650 100644 --- a/include/nonclient.h +++ b/include/nonclient.h @@ -12,8 +12,8 @@ extern void NC_GetInsideRect( HWND hwnd, RECT *rect ); extern void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POINT *minTrack, POINT *maxTrack ); -extern void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ); -extern LONG NC_HandleNCPaint( HWND hwnd ); +extern void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ); +extern LONG NC_HandleNCPaint( HWND hwnd , HRGN clip); extern LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam ); extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params ); extern LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ); diff --git a/include/options.h b/include/options.h index 1513a3a11c..c1b6f0eb00 100644 --- a/include/options.h +++ b/include/options.h @@ -18,7 +18,8 @@ typedef enum LANG_Fi, /* Finnish */ LANG_Da, /* Danish */ LANG_Cz, /* Czech */ - LANG_Eo /* Esperanto */ + LANG_Eo, /* Esperanto */ + LANG_It /* Italian */ } WINE_LANGUAGE; /* Supported modes */ diff --git a/include/pe_image.h b/include/pe_image.h index 944d2ff818..799392a721 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -25,13 +25,11 @@ typedef struct _WIN32_function{ typedef struct _WIN32_builtin{ char *name; WIN32_function *functions; - int size; - int base; + WIN32_function *last_func; + const int *base; struct _WIN32_builtin *next; } WIN32_builtin; -extern WIN32_builtin *WIN32_builtin_list; - struct w_files { struct w_files * next; diff --git a/include/selectors.h b/include/selectors.h index d06f13df4c..e826d8d2b0 100644 --- a/include/selectors.h +++ b/include/selectors.h @@ -17,8 +17,4 @@ extern WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size, enum seg_type type, BOOL is32bit, BOOL readonly ); -extern void CreateSelectors(void); - -extern WNDPROC GetWndProcEntry16( char *name ); - #endif /* __WINE_SELECTORS_H */ diff --git a/include/shell.h b/include/shell.h index 481f149329..d28caba375 100644 --- a/include/shell.h +++ b/include/shell.h @@ -7,11 +7,12 @@ #define __WINE_SHELL_H #include "windows.h" +#include "winreg.h" extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon); extern void SHELL_LoadRegistry(); extern void SHELL_SaveRegistry(); -extern BOOL SHELL_Init(); +extern void SHELL_Init(); #define SHELL_ERROR_SUCCESS 0L #define SHELL_ERROR_BADDB 1L @@ -23,20 +24,6 @@ extern BOOL SHELL_Init(); #define SHELL_ERROR_INVALID_PARAMETER 7L #define SHELL_ERROR_ACCESS_DENIED 8L -#define REG_SZ 1 /* string type */ - -#define HKEY_CLASSES_ROOT 1 - -typedef struct tagKEYSTRUCT { - HKEY hKey; - LPSTR lpSubKey; - DWORD dwType; - LPSTR lpValue; - struct tagKEYSTRUCT *lpPrevKey; - struct tagKEYSTRUCT *lpNextKey; - struct tagKEYSTRUCT *lpSubLvl; -} KEYSTRUCT, *LPKEYSTRUCT; - typedef struct { /* structure for dropped files */ WORD wSize; POINT ptMousePos; diff --git a/include/string32.h b/include/string32.h index a50bb010e1..eaadefdf0b 100644 --- a/include/string32.h +++ b/include/string32.h @@ -10,13 +10,15 @@ #include "wintypes.h" -int STRING32_UniLen(LPWSTR s); -void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src); -void STRING32_AnsiToUni(LPWSTR dest,LPCSTR src); -LPSTR STRING32_DupUniToAnsi(LPCWSTR src); -LPWSTR STRING32_DupAnsiToUni(LPCSTR src); -int STRING32_lstrcmpnW(LPCWSTR a,LPCWSTR b,DWORD len); -int STRING32_lstrcmpniW(LPCWSTR a,LPCWSTR b,DWORD len); -DWORD STRING32_lstrlenW(LPCWSTR); +int STRING32_UniLen(LPCWSTR s); +void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src); +void STRING32_AnsiToUni(LPWSTR dest,LPCSTR src); +LPSTR STRING32_DupUniToAnsi(LPCWSTR src); +LPWSTR STRING32_DupAnsiToUni(LPCSTR src); +int STRING32_lstrcmpnW(LPCWSTR a,LPCWSTR b,DWORD len); +int STRING32_lstrcmpniW(LPCWSTR a,LPCWSTR b,DWORD len); +DWORD STRING32_lstrlenW(LPCWSTR); +LPWSTR STRING32_strdupW(LPCWSTR); +int STRING32_lstrcmpW(LPCWSTR,LPCWSTR); #endif diff --git a/include/win.h b/include/win.h index 43b3fa6e2d..a4ecf1be40 100644 --- a/include/win.h +++ b/include/win.h @@ -82,7 +82,7 @@ extern void WIN_WalkWindows( HWND hwnd, int indent ); extern Window WIN_GetXWindow( HWND hwnd ); extern BOOL WIN_UnlinkWindow( HWND hwnd ); extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); -extern HWND WIN_FindWinToRepaint( HWND hwnd ); +extern HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue ); extern void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue ); extern BOOL WIN_CreateDesktopWindow(void); diff --git a/include/windows.h b/include/windows.h index fa91818c72..b823ad3dd9 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1088,6 +1088,20 @@ typedef OFSTRUCT *LPOFSTRUCT; #define DDL_DRIVES 0x4000 #define DDL_EXCLUSIVE 0x8000 +/* The security attributes structure + */ +typedef struct { + DWORD nLength; + void *lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + +typedef struct +{ + int dwLowDateTime; + int dwHighDateTime; +} FILETIME; + /* comm */ #define CBR_110 0xFF10 @@ -2885,7 +2899,7 @@ WORD GetInternalWindowPos(HWND,LPRECT,LPPOINT); int GetKBCodePage(void); int GetKerningPairs(HDC,int,LPKERNINGPAIR); int GetKeyNameText(LONG,LPSTR,int); -int GetKeyState(int); +INT GetKeyState(INT); void GetKeyboardState(BYTE*); int GetKeyboardType(int); HWND GetLastActivePopup(HWND); @@ -3143,13 +3157,55 @@ BOOL RectInRegion(HRGN,LPRECT); BOOL RectVisible(HDC,LPRECT); BOOL Rectangle(HDC,INT,INT,INT,INT); BOOL RedrawWindow(HWND,LPRECT,HRGN,UINT); -LONG RegCloseKey(HKEY); -LONG RegCreateKey(HKEY,LPCSTR,LPHKEY); -LONG RegDeleteKey(HKEY,LPCSTR); -LONG RegEnumKey(HKEY,DWORD,LPSTR,DWORD); -LONG RegOpenKey(HKEY,LPCSTR,LPHKEY); -LONG RegQueryValue(HKEY,LPCSTR,LPSTR,LPLONG); -LONG RegSetValue(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); +DWORD RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY); +DWORD RegOpenKeyW(HKEY,LPCWSTR,LPHKEY); +DWORD RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY); +DWORD RegOpenKeyA(HKEY,LPCSTR,LPHKEY); +DWORD RegOpenKey(HKEY,LPCSTR,LPHKEY); +DWORD RegCreateKeyExW(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM, + LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD); +DWORD RegCreateKeyW(HKEY,LPCWSTR,LPHKEY); +DWORD RegCreateKeyExA(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM, + LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD); +DWORD RegCreateKeyA(HKEY,LPCSTR,LPHKEY); +DWORD RegCreateKey(HKEY,LPCSTR,LPHKEY); +DWORD RegQueryValueExW(HKEY,LPWSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); +DWORD RegQueryValueW(HKEY,LPWSTR,LPWSTR,LPDWORD); +DWORD RegQueryValueExA(HKEY,LPSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); +DWORD RegQueryValueEx(HKEY,LPSTR,LPDWORD,LPDWORD,LPBYTE,LPDWORD); +DWORD RegQueryValueA(HKEY,LPSTR,LPSTR,LPDWORD); +DWORD RegQueryValue(HKEY,LPSTR,LPSTR,LPDWORD); +DWORD RegSetValueExW(HKEY,LPWSTR,DWORD,DWORD,LPBYTE,DWORD); +DWORD RegSetValueExA(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD); +DWORD RegSetValueEx(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD); +DWORD RegSetValueW(HKEY,LPCWSTR,DWORD,LPCWSTR,DWORD); +DWORD RegSetValueA(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); +DWORD RegSetValue(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); +DWORD RegEnumKeyExW(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,LPDWORD, + FILETIME*); +DWORD RegEnumKeyW(HKEY,DWORD,LPWSTR,DWORD); +DWORD RegEnumKeyExA(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPSTR,LPDWORD, + FILETIME*); +DWORD RegEnumKeyA(HKEY,DWORD,LPSTR,DWORD); +DWORD RegEnumKey(HKEY,DWORD,LPSTR,DWORD); +DWORD RegEnumValueW(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE, + LPDWORD); +DWORD RegEnumValueA(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE, + LPDWORD); +DWORD RegEnumValue(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE, + LPDWORD); +DWORD RegCloseKey(HKEY); +DWORD RegDeleteKeyW(HKEY,LPWSTR); +DWORD RegDeleteKeyA(HKEY,LPCSTR); +DWORD RegDeleteKey(HKEY,LPCSTR); +DWORD RegDeleteValueW(HKEY,LPWSTR); +DWORD RegDeleteValueA(HKEY,LPSTR); +DWORD RegDeleteValue(HKEY,LPSTR); +DWORD RegFlushKey(HKEY); +DWORD RegQueryInfoKeyW(HKEY,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD, + LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*); +DWORD RegQueryInfoKeyA(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD, + LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*); ATOM RegisterClass(LPWNDCLASS); WORD RegisterClipboardFormat(LPCSTR); WORD RegisterWindowMessage(SEGPTR); diff --git a/include/winerror.h b/include/winerror.h index 67e8d71ccf..cdca7ea1c7 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -7,6 +7,7 @@ extern int WIN32_LastError; */ #define ERROR_UNKNOWN 99999 +#define ERROR_SUCCESS 0 #define ERROR_FILE_NOT_FOUND 2 #define ERROR_TOO_MANY_OPEN_FILES 4 #define ERROR_ACCESS_DENIED 5 @@ -22,6 +23,8 @@ extern int WIN32_LastError; #define ERROR_DIR_NOT_EMPTY 145 #define ERROR_BUSY 170 #define ERROR_FILENAME_EXCED_RANGE 206 +#define ERROR_MORE_DATA 234 +#define ERROR_NO_MORE_ITEMS 259 #define ERROR_IO_DEVICE 1117 #define ERROR_POSSIBLE_DEADLOCK 1131 #define ERROR_BAD_DEVICE 1200 diff --git a/include/winreg.h b/include/winreg.h new file mode 100644 index 0000000000..01c60a0b4e --- /dev/null +++ b/include/winreg.h @@ -0,0 +1,111 @@ +/* + * Shell Library definitions + */ +#include "wintypes.h" + +#ifndef __WINE_WINREG_H +#define __WINE_WINREG_H + +#include "windows.h" + +/* FIXME: should be in security.h or whereever */ +#ifndef READ_CONTROL +#define READ_CONTROL 0x00020000 +#endif +#ifndef STANDARD_RIGHTS_READ +#define STANDARD_RIGHTS_READ READ_CONTROL +#endif +#ifndef STANDARD_RIGHTS_WRITE +#define STANDARD_RIGHTS_WRITE READ_CONTROL /* FIXME: hmm? */ +#endif +#ifndef STANDARD_RIGHTS_ALL +#define STANDARD_RIGHTS_ALL 0x001f0000 +#endif +/* ... */ + + +#define SHELL_ERROR_SUCCESS 0L +#define SHELL_ERROR_BADDB 1L +#define SHELL_ERROR_BADKEY 2L +#define SHELL_ERROR_CANTOPEN 3L +#define SHELL_ERROR_CANTREAD 4L +#define SHELL_ERROR_CANTWRITE 5L +#define SHELL_ERROR_OUTOFMEMORY 6L +#define SHELL_ERROR_INVALID_PARAMETER 7L +#define SHELL_ERROR_ACCESS_DENIED 8L + +#define REG_NONE 0 /* no type */ +#define REG_SZ 1 /* string type (ASCII) */ +#define REG_EXPAND_SZ 2 /* string, includes %ENVVAR% (expanded by caller) (ASCII) */ +#define REG_BINARY 3 /* binary format, callerspecific */ +/* YES, REG_DWORD == REG_DWORD_LITTLE_ENDIAN */ +#define REG_DWORD 4 /* DWORD in little endian format */ +#define REG_DWORD_LITTLE_ENDIAN 4 /* DWORD in little endian format */ +#define REG_DWORD_BIG_ENDIAN 5 /* DWORD in big endian format */ +#define REG_LINK 6 /* symbolic link (UNICODE) */ +#define REG_MULTI_SZ 7 /* multiple strings, delimited by \0, terminated by \0\0 (ASCII) */ +#define REG_RESOURCE_LIST 8 /* resource list? huh? */ +#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */ + +#define HKEY_CLASSES_ROOT 0x80000000 +#define HKEY_CURRENT_USER 0x80000001 +#define HKEY_LOCAL_MACHINE 0x80000002 +#define HKEY_USERS 0x80000003 +#define HKEY_PERFORMANCE_DATA 0x80000004 +#define HKEY_CURRENT_CONFIG 0x80000005 +#define HKEY_DYN_DATA 0x80000006 + +#define REG_OPTION_RESERVED 0x00000000 +#define REG_OPTION_NON_VOLATILE 0x00000000 +#define REG_OPTION_VOLATILE 0x00000001 +#define REG_OPTION_CREATE_LINK 0x00000002 + +#define REG_CREATED_NEW_KEY 0x00000001 +#define REG_OPENED_EXISTING_KEY 0x00000002 + +#define KEY_QUERY_VALUE 0x00000001 +#define KEY_SET_VALUE 0x00000002 +#define KEY_CREATE_SUB_KEY 0x00000004 +#define KEY_ENUMERATE_SUB_KEYS 0x00000008 +#define KEY_NOTIFY 0x00000010 +#define KEY_CREATE_LINK 0x00000020 + +#define KEY_READ (STANDARD_RIGHTS_READ| \ + KEY_QUERY_VALUE| \ + KEY_ENUMERATE_SUB_KEYS|\ + KEY_NOTIFY \ + ) +#define KEY_WRITE (STANDARD_RIGHTS_WRITE| \ + KEY_SET_VALUE| \ + KEY_CREATE_SUB_KEY \ + ) +#define KEY_EXECUTE KEY_READ +#define KEY_ALL_ACCESS (STANDARD_RIGHTS_ALL| \ + KEY_READ|KEY_WRITE| \ + KEY_CREATE_LINK \ + ) +/* one value of a key */ +typedef struct tagKEYVALUE { + LPWSTR name; /* name of value (UNICODE) or NULL for win31 */ + DWORD type; /* type of value */ + DWORD len; /* length of data */ + LPBYTE data; /* content, may be strings, binaries, etc. */ +} KEYVALUE,*LPKEYVALUE; + +/* a registry key */ +typedef struct tagKEYSTRUCT { + LPWSTR keyname; /* name of THIS key (UNICODE) */ + DWORD flags; /* flags. */ + LPWSTR class; + /* values */ + DWORD nrofvalues; /* nr of values in THIS key */ + LPKEYVALUE values; /* values in THIS key */ + /* key management pointers */ + struct tagKEYSTRUCT *next; /* next key on same hierarchy */ + struct tagKEYSTRUCT *nextsub; /* keys that hang below THIS key */ +} KEYSTRUCT, *LPKEYSTRUCT; + +void SHELL_Init(); +void SHELL_SaveRegistry(); +void SHELL_LoadRegistry(); +#endif /* __WINE_WINREG_H */ diff --git a/include/wintypes.h b/include/wintypes.h index 52e054886b..8f53926070 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -49,6 +49,7 @@ typedef LONG LRESULT; typedef INT HFILE; typedef DWORD HHOOK; typedef char *LPSTR; +typedef BYTE *LPBYTE; typedef const char *LPCSTR; typedef TCHAR *LPTSTR; typedef const TCHAR *LPCTSTR; @@ -64,6 +65,8 @@ typedef void *LPVOID; typedef const void *LPCVOID; typedef WORD CATCHBUF[9]; typedef WORD *LPCATCHBUF; +typedef DWORD ACCESS_MASK; +typedef ACCESS_MASK REGSAM; #define DECLARE_HANDLE(a) typedef HANDLE a; diff --git a/library/miscstubs.c b/library/miscstubs.c index b06c6a6fb4..0c3f8c111f 100644 --- a/library/miscstubs.c +++ b/library/miscstubs.c @@ -169,11 +169,11 @@ LRESULT ErrorProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) } /*********************************************************************** - * GetWndProcEntry16 (not a Windows API function) + * MODULE_GetWndProcEntry16 (not a Windows API function) * * Return an entry point from the WINPROCS dll. */ -WNDPROC GetWndProcEntry16( char *name ) +WNDPROC MODULE_GetWndProcEntry16( char *name ) { #define MAP_STR_TO_PROC(str,proc) if(!strcmp(name,str))return proc MAP_STR_TO_PROC("ActivateAppProc",ACTIVATEAPP_callback); @@ -202,3 +202,13 @@ WNDPROC GetWndProcEntry16( char *name ) fprintf(stderr,"warning: No mapping for %s(), add one in library/miscstubs.c\n",name); return ErrorProc; } + +/*********************************************************************** + * MODULE_GetWndProcEntry32 (not a Windows API function) + * + * Return an entry point from the WINPROCS32 dll. + */ +WNDPROC MODULE_GetWndProcEntry32( char *name ) +{ + return MODULE_GetWndProcEntry16( name ); +} diff --git a/loader/main.c b/loader/main.c index 0aca285c38..0c49037597 100644 --- a/loader/main.c +++ b/loader/main.c @@ -11,11 +11,13 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include "windows.h" +#include "alias.h" #include "module.h" #include "task.h" #include "selectors.h" #include "comm.h" #include "user.h" +#include "win.h" #include "menu.h" #include "kernel32.h" #include "atom.h" @@ -99,10 +101,13 @@ int MAIN_Init(void) /* Global atom table initialisation */ if (!ATOM_Init()) return 0; - + /* GDI initialisation */ if (!GDI_Init()) return 0; + /* Initialise window procedures aliases */ + if (!ALIAS_Init()) return 0; + /* Initialize system colors and metrics*/ SYSMETRICS_Init(); SYSCOLOR_Init(); diff --git a/loader/module.c b/loader/module.c index 7cece765d7..fce734c615 100644 --- a/loader/module.c +++ b/loader/module.c @@ -48,20 +48,18 @@ static HMODULE MODULE_LoadBuiltin( LPCSTR name, BOOL force ) NE_MODULE *pModule; SEGTABLEENTRY *pSegTable; struct dll_table_s *table; - int i; char dllname[16], *p; /* Fix the name in case we have a full path and extension */ if ((p = strrchr( name, '\\' ))) name = p + 1; - strncpy( dllname, name, 15 ); - dllname[15] = '\0'; + lstrcpyn( dllname, name, sizeof(dllname) ); if ((p = strrchr( dllname, '.' ))) *p = '\0'; - for (i = 0, table = dll_builtin_table; i < N_BUILTINS; i++, table++) + for (table = dll_builtin_table; table->name; table++) if (!lstrcmpi( table->name, dllname )) break; - if (i >= N_BUILTINS) return 0; - if (!table->used && !force) return 0; + if (!table->name) return 0; + if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0; hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start, table->module_end - table->module_start, @@ -486,6 +484,10 @@ HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs ) } } + /* Clear internal Wine flags in case they are set in the EXE file */ + + pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32); + /* Store the filename information */ pModule->fileinfo = (int)pData - (int)pModule; @@ -601,7 +603,7 @@ HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs ) * * Lookup the ordinal for a given name. */ -WORD MODULE_GetOrdinal( HMODULE hModule, char *name ) +WORD MODULE_GetOrdinal( HMODULE hModule, const char *name ) { char buffer[256], *cpnt; BYTE len; @@ -630,7 +632,6 @@ WORD MODULE_GetOrdinal( HMODULE hModule, char *name ) cpnt += *cpnt + 1 + sizeof(WORD); while (*cpnt) { - dprintf_module( stddeb, " Checking '%*.*s'\n", *cpnt, *cpnt, cpnt+1 ); if (((BYTE)*cpnt == len) && !memcmp( cpnt+1, buffer, len )) { dprintf_module( stddeb, " Found: ordinal=%d\n", @@ -649,7 +650,6 @@ WORD MODULE_GetOrdinal( HMODULE hModule, char *name ) cpnt += *cpnt + 1 + sizeof(WORD); while (*cpnt) { - dprintf_module( stddeb, " Checking '%*.*s'\n", *cpnt, *cpnt, cpnt+1 ); if (((BYTE)*cpnt == len) && !memcmp( cpnt+1, buffer, len )) { dprintf_module( stddeb, " Found: ordinal=%d\n", @@ -793,6 +793,40 @@ LPSTR MODULE_GetEntryPointName( HMODULE hModule, WORD ordinal ) } +/*********************************************************************** + * MODULE_GetWndProcEntry16 (not a Windows API function) + * + * Return an entry point from the WINPROCS dll. + */ +#ifndef WINELIB +WNDPROC MODULE_GetWndProcEntry16( const char *name ) +{ + WORD ordinal; + static HMODULE hModule = 0; + + if (!hModule) hModule = GetModuleHandle( "WINPROCS" ); + ordinal = MODULE_GetOrdinal( hModule, name ); + return MODULE_GetEntryPoint( hModule, ordinal ); +} +#endif + + +/*********************************************************************** + * MODULE_GetWndProcEntry32 (not a Windows API function) + * + * Return an entry point from the WINPROCS32 dll. + */ +#ifndef WINELIB +WNDPROC MODULE_GetWndProcEntry32( const char *name ) +{ + static HMODULE hModule = 0; + + if (!hModule) hModule = GetModuleHandle( "WINPROCS32" ); + return PE_GetProcAddress( hModule, name ); +} +#endif + + /*********************************************************************** * MODULE_GetModuleName */ @@ -1103,10 +1137,6 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock ) /* the module, even if it contains circular DLL references */ pModule->count = 1; - - /* Clear built-in flag in case it was set in the EXE file */ - - pModule->flags &= ~NE_FFLAGS_BUILTIN; } else { @@ -1422,24 +1452,6 @@ WORD GetExpWinVer( HMODULE hModule ) } -/*********************************************************************** - * GetWndProcEntry16 (not a Windows API function) - * - * Return an entry point from the WINPROCS dll. - */ -#ifndef WINELIB -WNDPROC GetWndProcEntry16( char *name ) -{ - WORD ordinal; - static HMODULE hModule = 0; - - if (!hModule) hModule = GetModuleHandle( "WINPROCS" ); - ordinal = MODULE_GetOrdinal( hModule, name ); - return MODULE_GetEntryPoint( hModule, ordinal ); -} -#endif - - /********************************************************************** * ModuleFirst (TOOLHELP.59) */ diff --git a/loader/ne_image.c b/loader/ne_image.c index 1b8c0a64ff..8ae9004bfd 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c @@ -510,11 +510,11 @@ void NE_InitializeDLLs( HMODULE hModule ) HMODULE *pDLL; pModule = (NE_MODULE *)GlobalLock( hModule ); - if (pModule->magic == PE_SIGNATURE) - { - PE_InitializeDLLs(hModule); - return; - } + if (pModule->flags & NE_FFLAGS_WIN32) + { + PE_InitializeDLLs(hModule); + return; + } if (pModule->dlls_to_init) { HANDLE to_init = pModule->dlls_to_init; diff --git a/loader/pe_image.c b/loader/pe_image.c index e95ade2bfe..ced45d012b 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -29,7 +29,6 @@ #include "task.h" #include "ldt.h" #include "registers.h" -#include "selectors.h" #include "stddebug.h" #include "debug.h" #include "xmalloc.h" @@ -581,10 +580,10 @@ HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params ) pModule = (NE_MODULE*)GlobalLock(hModule); /* Set all used entries */ - pModule->magic=PE_SIGNATURE; + pModule->magic=NE_SIGNATURE; pModule->count=1; pModule->next=0; - pModule->flags=0; + pModule->flags=NE_FFLAGS_WIN32; pModule->dgroup=1; pModule->ss=1; pModule->cs=2; @@ -610,7 +609,7 @@ HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params ) pSegment->minsize=0x1000; pSegment++; - cts=(DWORD)GetWndProcEntry16("Win32CallToStart"); + cts=(DWORD)MODULE_GetWndProcEntry16("Win32CallToStart"); #ifdef WINELIB32 pSegment->selector=(void*)cts; pModule->ip=0; diff --git a/loader/resource.c b/loader/resource.c index dee9027f44..0de3993e58 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -37,7 +37,7 @@ */ HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) { - WORD *pModule; + NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ dprintf_resource(stddeb, "FindResource: module=%04x type=", hModule ); @@ -52,17 +52,14 @@ HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) dprintf_resource( stddeb, " name=" ); PrintId( name ); dprintf_resource( stddeb, "\n" ); - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; #ifndef WINELIB - switch(*pModule) + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_FindResource( hModule, type, name ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to FindResource() for Win32 module\n"); return 0; } + return NE_FindResource( hModule, type, name ); #else return LIBRES_FindResource( hModule, name, type ); #endif @@ -74,23 +71,20 @@ HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) */ HGLOBAL LoadResource( HMODULE hModule, HRSRC hRsrc ) { - WORD *pModule; + NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n", hModule, hRsrc ); if (!hRsrc) return 0; - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; #ifndef WINELIB - switch(*pModule) + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_LoadResource( hModule, hRsrc ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to LoadResource() for Win32 module\n"); return 0; } + return NE_LoadResource( hModule, hRsrc ); #else return LIBRES_LoadResource( hModule, hRsrc ); #endif @@ -105,21 +99,18 @@ SEGPTR WIN16_LockResource( HGLOBAL handle ) { #ifndef WINELIB HMODULE hModule; - WORD *pModule; + NE_MODULE *pModule; dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle ); if (!handle) return (SEGPTR)0; hModule = GetExePtr( handle ); - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; - switch(*pModule) + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_LockResource( hModule, handle ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to LockResource() for Win32 module\n"); return 0; } + return NE_LockResource( hModule, handle ); #else return LIBRES_LockResource( handle ); #endif @@ -130,21 +121,18 @@ LPVOID LockResource( HGLOBAL handle ) { #ifndef WINELIB HMODULE hModule; - WORD *pModule; + NE_MODULE *pModule; dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle ); if (!handle) return NULL; hModule = GetExePtr( handle ); - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; - switch(*pModule) + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to LockResource() for Win32 module\n"); return 0; } + return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) ); #else return LIBRES_LockResource( handle ); #endif @@ -158,21 +146,18 @@ BOOL FreeResource( HGLOBAL handle ) { #ifndef WINELIB HMODULE hModule; - WORD *pModule; + NE_MODULE *pModule; dprintf_resource(stddeb, "FreeResource: handle=%04x\n", handle ); if (!handle) return FALSE; hModule = GetExePtr( handle ); - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; - switch(*pModule) + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_FreeResource( hModule, handle ); - case PE_SIGNATURE: - return FALSE; - default: - return FALSE; + fprintf(stderr,"Don't know how to FreeResource() for Win32 module\n"); + return 0; } + return NE_FreeResource( hModule, handle ); #else return LIBRES_FreeResource( handle ); #endif @@ -184,25 +169,22 @@ BOOL FreeResource( HGLOBAL handle ) */ INT AccessResource( HINSTANCE hModule, HRSRC hRsrc ) { - WORD *pModule; + NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n", hModule, hRsrc ); if (!hRsrc) return 0; - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; #ifndef WINELIB - switch(*pModule) + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_AccessResource( hModule, hRsrc ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to AccessResource() for Win32 module\n"); return 0; } + return NE_AccessResource( hModule, hRsrc ); #else - return LIBRES_AccessResource( hModule, hRsrc ); + return LIBRES_AccessResource( hModule, hRsrc ); #endif } @@ -212,22 +194,19 @@ INT AccessResource( HINSTANCE hModule, HRSRC hRsrc ) */ DWORD SizeofResource( HMODULE hModule, HRSRC hRsrc ) { - WORD *pModule; + NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n", hModule, hRsrc ); - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; #ifndef WINELIB - switch(*pModule) + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_SizeofResource( hModule, hRsrc ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to SizeOfResource() for Win32 module\n"); return 0; } + return NE_SizeofResource( hModule, hRsrc ); #else return LIBRES_SizeofResource( hModule, hRsrc ); #endif @@ -239,23 +218,20 @@ DWORD SizeofResource( HMODULE hModule, HRSRC hRsrc ) */ HGLOBAL AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ) { - WORD *pModule; + NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); if (!hRsrc) return 0; - if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; + if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; #ifndef WINELIB - switch(*pModule) + if (pModule->flags & NE_FFLAGS_WIN32) { - case NE_SIGNATURE: - return NE_AllocResource( hModule, hRsrc, size ); - case PE_SIGNATURE: - return 0; - default: + fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n"); return 0; } + return NE_AllocResource( hModule, hRsrc, size ); #else return LIBRES_AllocResource( hModule, hRsrc, size ); #endif @@ -350,9 +326,9 @@ int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg) (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) { INT mask = 0; - if(GetKeyState(VK_SHIFT) & 0xf) mask |= SHIFT_ACCEL; - if(GetKeyState(VK_CONTROL) & 0xf) mask |= CONTROL_ACCEL; - if(GetKeyState(VK_MENU) & 0xf) mask |= ALT_ACCEL; + if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL; + if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL; + if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL; if(mask == (lpAccelTbl->tbl[i].type & (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) { SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, diff --git a/loader/signal.c b/loader/signal.c index 995741b4b6..8ebc0b6883 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -7,6 +7,9 @@ #include #include +#include +#include + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) #include #include @@ -43,7 +46,33 @@ wine_sigaction(int sig,struct sigaction * new, struct sigaction * old) #endif -#if defined(linux) +/********************************************************************** + * wine_timer + * + * SIGALRM handler. + */ +#ifdef linux +static void wine_timer(int signal, struct sigcontext_struct context_struct) +{ +#elif defined(__svr4__) +static void wine_timer(int signal, void *siginfo, ucontext_t *context) +{ +#else +static void wine_timer(int signal, int code, struct sigcontext *context) +{ +#endif + /* Should do real-time timers here */ + + DOSMEM_Tick(); +} + + +/********************************************************************** + * win_fault + * + * Segfault handler. + */ +#ifdef linux static void win_fault(int signal, struct sigcontext_struct context_struct) { struct sigcontext_struct *context = &context_struct; @@ -99,6 +128,7 @@ static void SIGNAL_SetHandler( int sig, void (*func)() ) #ifdef linux sig_act.sa_handler = func; + sig_act.sa_flags = SA_RESTART; /* Point to the top of the stack, minus 4 just in case, and make it aligned */ sig_act.sa_restorer = @@ -131,14 +161,14 @@ static void SIGNAL_SetHandler( int sig, void (*func)() ) } } +extern void stop_wait(int a); + /********************************************************************** * init_wine_signals */ void init_wine_signals(void) { - extern void stop_wait(int a); - #if defined(__NetBSD__) || defined(__FreeBSD__) struct sigaltstack ss; @@ -174,7 +204,8 @@ void init_wine_signals(void) exit(1); } #endif /* __svr4__ */ - + + SIGNAL_SetHandler( SIGALRM, (void (*)())wine_timer ); SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault ); SIGNAL_SetHandler( SIGILL, (void (*)())win_fault ); SIGNAL_SetHandler( SIGFPE, (void (*)())win_fault ); @@ -186,6 +217,24 @@ void init_wine_signals(void) #ifdef CONFIG_IPC SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */ #endif + SIGNAL_StartBIOSTimer(); +} + + +/********************************************************************** + * SIGNAL_StartTimer + * + * Start the BIOS tick timer. + */ +void SIGNAL_StartBIOSTimer(void) +{ + struct itimerval vt_timer; + + vt_timer.it_interval.tv_sec = 0; + vt_timer.it_interval.tv_usec = 54929; + vt_timer.it_value = vt_timer.it_interval; + + setitimer(ITIMER_REAL, &vt_timer, NULL); } #endif /* ifndef WINELIB */ diff --git a/loader/task.c b/loader/task.c index 1b6c55747b..0fc4a674fd 100644 --- a/loader/task.c +++ b/loader/task.c @@ -21,7 +21,6 @@ #include "neexe.h" #include "options.h" #include "queue.h" -#include "selectors.h" #include "toolhelp.h" #include "stddebug.h" #include "debug.h" @@ -34,6 +33,9 @@ /* Must not be greater than 64k, or MAKE_SEGPTR won't work */ #define STACK32_SIZE 0x10000 +extern void TIMER_SwitchQueue(HQUEUE, HQUEUE ); +extern void TIMER_NukeTimers(HWND, HQUEUE ); + /* ------ Internal variables ------ */ static HTASK hFirstTask = 0; @@ -61,7 +63,7 @@ static HANDLE TASK_CreateDOSEnvironment(void); */ BOOL TASK_Init(void) { - TASK_RescheduleProc = (FARPROC)GetWndProcEntry16( "TASK_Reschedule" ); + TASK_RescheduleProc = MODULE_GetWndProcEntry16( "TASK_Reschedule" ); if (!(hDOSEnvironment = TASK_CreateDOSEnvironment())) fprintf( stderr, "Not enough memory for DOS Environment\n" ); return (hDOSEnvironment != 0); @@ -581,6 +583,10 @@ static void TASK_DeleteTask( HTASK hTask ) FILE_CloseAllFiles( pTask->hPDB ); + /* Nuke timers */ + + TIMER_NukeTimers( 0, pTask->hQueue ); + /* Free the message queue */ QUEUE_DeleteMsgQueue( pTask->hQueue ); @@ -999,8 +1005,12 @@ HQUEUE SetTaskQueue( HANDLE hTask, HQUEUE hQueue ) if (!hTask) hTask = hCurrentTask; if (!(pTask = (TDB *)GlobalLock( hTask ))) return 0; + hPrev = pTask->hQueue; pTask->hQueue = hQueue; + + TIMER_SwitchQueue( hPrev, hQueue ); + return hPrev; } @@ -1153,8 +1163,6 @@ HMODULE GetExePtr( HANDLE handle ) if (!(ptr = GlobalLock( handle ))) return 0; if (((NE_MODULE *)ptr)->magic == NE_SIGNATURE) return handle; - /* Fake modules describing PE modules have a PE signature */ - if (((NE_MODULE *)ptr)->magic == PE_SIGNATURE) return handle; /* Check the owner for module handle */ @@ -1165,7 +1173,6 @@ HMODULE GetExePtr( HANDLE handle ) #endif if (!(ptr = GlobalLock( owner ))) return 0; if (((NE_MODULE *)ptr)->magic == NE_SIGNATURE) return owner; - if (((NE_MODULE *)ptr)->magic == PE_SIGNATURE) return owner; /* Search for this handle and its owner inside all tasks */ diff --git a/misc/Makefile.in b/misc/Makefile.in index 4196c1cf03..1266b0570c 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -21,6 +21,7 @@ C_SRCS = \ olesvr.c \ port.c \ rect.c \ + registry.c \ shell.c \ sound.c \ spy.c \ diff --git a/misc/commdlg.c b/misc/commdlg.c index 3d242f799e..66beced576 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -12,7 +12,7 @@ #include "message.h" #include "commdlg.h" #include "dlgs.h" -#include "selectors.h" +#include "module.h" #include "resource.h" #include "dos_fs.h" #include "drive.h" @@ -83,7 +83,7 @@ BOOL GetOpenFileName(LPOPENFILENAME lpofn) hInst = WIN_GetWindowInstance( lpofn->hwndOwner ); bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner, - GetWndProcEntry16("FileOpenDlgProc"), + MODULE_GetWndProcEntry16("FileOpenDlgProc"), (DWORD)lpofn ); if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)) @@ -125,7 +125,7 @@ BOOL GetSaveFileName(LPOPENFILENAME lpofn) hInst = WIN_GetWindowInstance( lpofn->hwndOwner ); bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner, - GetWndProcEntry16("FileSaveDlgProc"), + MODULE_GetWndProcEntry16("FileSaveDlgProc"), (DWORD)lpofn); if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)) { @@ -686,7 +686,7 @@ BOOL ChooseColor(LPCHOOSECOLOR lpChCol) hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR ); hInst = WIN_GetWindowInstance( lpChCol->hwndOwner ); bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChCol->hwndOwner, - GetWndProcEntry16("ColorDlgProc"), + MODULE_GetWndProcEntry16("ColorDlgProc"), (DWORD)lpChCol ); SYSRES_FreeResource( hDlgTmpl ); return bRet; @@ -741,7 +741,7 @@ BOOL FindText(LPFINDREPLACE lpFind) hInst = WIN_GetWindowInstance( lpFind->hwndOwner ); if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1; bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner, - GetWndProcEntry16("FindTextDlgProc"), + MODULE_GetWndProcEntry16("FindTextDlgProc"), (DWORD)lpFind ); GlobalUnlock( hDlgTmpl ); SYSRES_FreeResource( hDlgTmpl ); @@ -770,7 +770,7 @@ BOOL ReplaceText(LPFINDREPLACE lpFind) hInst = WIN_GetWindowInstance( lpFind->hwndOwner ); if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1; bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner, - GetWndProcEntry16("ReplaceTextDlgProc"), + MODULE_GetWndProcEntry16("ReplaceTextDlgProc"), (DWORD)lpFind ); GlobalUnlock( hDlgTmpl ); SYSRES_FreeResource( hDlgTmpl ); @@ -1017,8 +1017,8 @@ BOOL PrintDlg(LPPRINTDLG lpPrint) hInst = WIN_GetWindowInstance( lpPrint->hwndOwner ); bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpPrint->hwndOwner, (lpPrint->Flags & PD_PRINTSETUP) ? - GetWndProcEntry16("PrintSetupDlgProc") : - GetWndProcEntry16("PrintDlgProc"), + MODULE_GetWndProcEntry16("PrintSetupDlgProc") : + MODULE_GetWndProcEntry16("PrintDlgProc"), (DWORD)lpPrint ); SYSRES_FreeResource( hDlgTmpl ); return bRet; diff --git a/misc/keyboard.c b/misc/keyboard.c index 8058a7c068..8f8c31b262 100644 --- a/misc/keyboard.c +++ b/misc/keyboard.c @@ -6,6 +6,7 @@ static char Copyright[] = "Copyright Scott A. Laird, Erik Bos 1993, 1994"; #include #include #include +#include #include "windows.h" #include "keyboard.h" #include "stddebug.h" @@ -19,14 +20,27 @@ int ToAscii(WORD wVirtKey, WORD wScanCode, LPSTR lpKeyState, dprintf_keyboard(stddeb,"ToAscii (%d,%d)\n",wVirtKey, wScanCode); - /* FIXME: this is not sufficient but better than returing -1 */ + /* FIXME: codepage is broken */ for (i = 0 ; i != KeyTableSize ; i++) - if (KeyTable[i].virtualkey == wVirtKey) { - *(BYTE*)lpChar++ = *KeyTable[i].name; - *(BYTE*)lpChar = 0; + if (KeyTable[i].virtualkey == wVirtKey) + { + dprintf_keyboard(stddeb,"\t\tchar = %s\n", KeyTable[i].name); + if( isprint(KeyTable[i].ASCII) || isspace(KeyTable[i].ASCII) ) + { + *(BYTE*)lpChar = KeyTable[i].ASCII; + *(((BYTE*)lpChar) + 1) = 0; + + if( isalpha( *(BYTE*)lpChar ) ) + if( (lpKeyState[VK_CAPITAL]<0 && !lpKeyState[VK_SHIFT]) || + (!lpKeyState[VK_CAPITAL] && lpKeyState[VK_SHIFT]<0) ) + *(BYTE*)lpChar = toupper( *(BYTE*)lpChar ); + else + *(BYTE*)lpChar = tolower( *(BYTE*)lpChar ); + return 1; - } + } + } *(BYTE*)lpChar = 0; return 0; diff --git a/misc/main.c b/misc/main.c index 34f3b95883..caa253f4e2 100644 --- a/misc/main.c +++ b/misc/main.c @@ -57,6 +57,7 @@ static const char *langNames[] = "Da", /* LANG_Da */ "Cz", /* LANG_Cz */ "Eo", /* LANG_Eo */ + "It", /* LANG_It */ NULL }; @@ -139,7 +140,7 @@ static XrmOptionDescRec optionsTable[] = " -fixedmap Use a \"standard\" color map\n" \ " -iconic Start as an icon\n" \ " -ipc Enable IPC facilities\n" \ - " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo)\n" \ + " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It)\n" \ " -managed Allow the window manager to manage created windows\n" \ " -mode mode Start Wine in a particular mode (standard or enhanced)\n" \ " -name name Set the application name\n" \ @@ -265,32 +266,32 @@ BOOL ParseDebugOptions(char *options) */ static BOOL MAIN_ParseDLLOptions(char *options) { - int l; - int i; - if (strlen(options)<3) - return FALSE; - do - { - if ((*options!='+')&&(*options!='-')) - return FALSE; - if (strchr(options,',')) - l=strchr(options,',')-options; - else l=strlen(options); - for (i=0;iname; dll++) + { + if (!lstrncmpi(options+1,dll->name,l-1)) + { + if (*options == '+') dll->flags &= ~DLL_FLAG_NOT_USED; + else dll->flags |= DLL_FLAG_NOT_USED; + break; + } + } + if (!dll->name) return FALSE; + options+=l; + } + while((*options==',')&&(*(++options))); + if (*options) + return FALSE; + else + return TRUE; } #endif @@ -433,12 +434,12 @@ static void MAIN_ParseOptions( int *argc, char *argv[] ) if(MAIN_ParseDLLOptions((char*)value.addr)==FALSE) { int i; + BUILTIN_DLL *dll; fprintf(stderr,"%s: Syntax: -dll +xxx,... or -dll -xxx,...\n",argv[0]); fprintf(stderr,"Example: -dll -ole2 Do not use emulated OLE2.DLL\n"); fprintf(stderr,"Available DLLs\n"); - for(i=0;iname; dll++) + fprintf(stderr,"%-9s%c",dll->name, (((i+2)%8==0)?'\n':' ')); fprintf(stderr,"\n\n"); exit(1); } diff --git a/misc/ole2nls.c b/misc/ole2nls.c index 51cd354ef6..fc93301dce 100644 --- a/misc/ole2nls.c +++ b/misc/ole2nls.c @@ -32,6 +32,7 @@ DWORD WINAPI GetUserDefaultLCID() case LANG_Da: case LANG_Cz: case LANG_Eo: + case LANG_It: default: return 0; /* Neutral language */ } @@ -523,6 +524,130 @@ LOCVAL(LOCALE_SABBREVMONTHNAME13,"") /* LOCVAL(LOCALE_INEGSYMPRECEDES) */ /* LOCVAL(LOCALE_INEGSEPBYSPACE) */ break; /* LANG(Eo) */ + + case LANG_It: +LOCVAL(LOCALE_ILANGUAGE,"9") +LOCVAL(LOCALE_SLANGUAGE,"Italiano") +LOCVAL(LOCALE_SENGLANGUAGE,"Italian") +LOCVAL(LOCALE_SABBREVLANGNAME,"ita") +LOCVAL(LOCALE_SNATIVELANGNAME,"Italiano") +LOCVAL(LOCALE_ICOUNTRY,"39") +LOCVAL(LOCALE_SCOUNTRY,"Italia") +LOCVAL(LOCALE_SENGCOUNTRY,"Italy") +LOCVAL(LOCALE_SABBREVCTRYNAME,"It") +LOCVAL(LOCALE_SNATIVECTRYNAME,"Italia") +LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9") +LOCVAL(LOCALE_IDEFAULTCOUNTRY,"39") +/* Dunno +LOCVAL(LOCALE_IDEFAULTCODEPAGE) +LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) +*/ +LOCVAL(LOCALE_SLIST,";") +LOCVAL(LOCALE_IMEASURE,"0") +LOCVAL(LOCALE_SDECIMAL,",") +LOCVAL(LOCALE_STHOUSAND,".") +/* +LOCVAL(LOCALE_SGROUPING) +*/ +LOCVAL(LOCALE_IDIGITS,"2") +LOCVAL(LOCALE_ILZERO,"1") +/* +LOCVAL(LOCALE_INEGNUMBER) +Is this "0123456789" ?? +LOCVAL(LOCALE_SNATIVEDIGITS) +*/ +LOCVAL(LOCALE_SCURRENCY,"Lit.") +/* +LOCVAL(LOCALE_SINTLSYMBOL) +LOCVAL(LOCALE_SMONDECIMALSEP) +LOCVAL(LOCALE_SMONTHOUSANDSEP) +LOCVAL(LOCALE_SMONGROUPING) +*/ +LOCVAL(LOCALE_ICURRDIGITS,"2") +/* +LOCVAL(LOCALE_IINTLCURRDIGITS) +*/ +LOCVAL(LOCALE_ICURRENCY,"3") +LOCVAL(LOCALE_INEGCURR,"8") +LOCVAL(LOCALE_SDATE,".") +LOCVAL(LOCALE_STIME,":") +LOCVAL(LOCALE_SSHORTDATE,"dd.MM.yyyy") +LOCVAL(LOCALE_SLONGDATE,"ddd, d. MMMM yyyy") +/* +LOCVAL(LOCALE_STIMEFORMAT) +*/ +LOCVAL(LOCALE_IDATE,"1") +/* +LOCVAL(LOCALE_ILDATE) +*/ +LOCVAL(LOCALE_ITIME,"1") +/* +LOCVAL(LOCALE_ITIMEMARKPOSN) +LOCVAL(LOCALE_ICENTURY) +*/ +LOCVAL(LOCALE_ITLZERO,"1") +/* +LOCVAL(LOCALE_IDAYLZERO) +LOCVAL(LOCALE_IMONLZERO) +LOCVAL(LOCALE_S1159) +LOCVAL(LOCALE_S2359) +LOCVAL(LOCALE_ICALENDARTYPE) +LOCVAL(LOCALE_IOPTIONALCALENDAR) +LOCVAL(LOCALE_IFIRSTDAYOFWEEK) +LOCVAL(LOCALE_IFIRSTWEEKOFYEAR) +*/ +LOCVAL(LOCALE_SDAYNAME1,"Lunedi'") +LOCVAL(LOCALE_SDAYNAME2,"Martedi'") +LOCVAL(LOCALE_SDAYNAME3,"Mercoledi'") +LOCVAL(LOCALE_SDAYNAME4,"Giovedi'") +LOCVAL(LOCALE_SDAYNAME5,"Venerdi'") +LOCVAL(LOCALE_SDAYNAME6,"Sabato") +LOCVAL(LOCALE_SDAYNAME7,"Domenica") +LOCVAL(LOCALE_SABBREVDAYNAME1,"Lu") +LOCVAL(LOCALE_SABBREVDAYNAME2,"Ma") +LOCVAL(LOCALE_SABBREVDAYNAME3,"Me") +LOCVAL(LOCALE_SABBREVDAYNAME4,"Gi") +LOCVAL(LOCALE_SABBREVDAYNAME5,"Ve") +LOCVAL(LOCALE_SABBREVDAYNAME6,"Sa") +LOCVAL(LOCALE_SABBREVDAYNAME7,"Do") +LOCVAL(LOCALE_SMONTHNAME1,"Gennaio") +LOCVAL(LOCALE_SMONTHNAME2,"Febbraio") +LOCVAL(LOCALE_SMONTHNAME3,"Marzo") +LOCVAL(LOCALE_SMONTHNAME4,"Aprile") +LOCVAL(LOCALE_SMONTHNAME5,"Maggio") +LOCVAL(LOCALE_SMONTHNAME6,"Giugno") +LOCVAL(LOCALE_SMONTHNAME7,"Luglio") +LOCVAL(LOCALE_SMONTHNAME8,"Agosto") +LOCVAL(LOCALE_SMONTHNAME9,"Settembre") +LOCVAL(LOCALE_SMONTHNAME10,"Ottobre") +LOCVAL(LOCALE_SMONTHNAME11,"Novembre") +LOCVAL(LOCALE_SMONTHNAME12,"Dicembre") +LOCVAL(LOCALE_SMONTHNAME13,"") +LOCVAL(LOCALE_SABBREVMONTHNAME1,"Gen") +LOCVAL(LOCALE_SABBREVMONTHNAME2,"Feb") +LOCVAL(LOCALE_SABBREVMONTHNAME3,"Mar") +LOCVAL(LOCALE_SABBREVMONTHNAME4,"Apr") +LOCVAL(LOCALE_SABBREVMONTHNAME5,"Mag") +LOCVAL(LOCALE_SABBREVMONTHNAME6,"Giu") +LOCVAL(LOCALE_SABBREVMONTHNAME7,"Lug") +LOCVAL(LOCALE_SABBREVMONTHNAME8,"Ago") +LOCVAL(LOCALE_SABBREVMONTHNAME9,"Set") +LOCVAL(LOCALE_SABBREVMONTHNAME10,"Ott") +LOCVAL(LOCALE_SABBREVMONTHNAME11,"Nov") +LOCVAL(LOCALE_SABBREVMONTHNAME12,"Dic") +LOCVAL(LOCALE_SABBREVMONTHNAME13,"") +/* +LOCVAL(LOCALE_SPOSITIVESIGN) +LOCVAL(LOCALE_SNEGATIVESIGN) +LOCVAL(LOCALE_IPOSSIGNPOSN) +LOCVAL(LOCALE_INEGSIGNPOSN) +LOCVAL(LOCALE_IPOSSYMPRECEDES) +LOCVAL(LOCALE_IPOSSEPBYSPACE) +LOCVAL(LOCALE_INEGSYMPRECEDES) +LOCVAL(LOCALE_INEGSEPBYSPACE) +*/ + break; /* LANG(It) */ + /*Insert other languages here*/ diff --git a/misc/registry.c b/misc/registry.c new file mode 100644 index 0000000000..1cff39f328 --- /dev/null +++ b/misc/registry.c @@ -0,0 +1,1885 @@ +/* + * Registry Functions + * + * Copyright 1996 Marcus Meissner + */ + +#include +#include +#include +#include +#include +#include "windows.h" +#include "win.h" +#include "winerror.h" +#include "string32.h" +#include "kernel32.h" /* LPSECURITY_ATTRIBUTES */ +#include "stddebug.h" +#include "debug.h" +#include "xmalloc.h" +#include "winreg.h" + +#define SAVE_CLASSES_ROOT "/tmp/reg.classes_root" +#define SAVE_CURRENT_USER "/tmp/reg.current_user" +#define SAVE_LOCAL_MACHINE "/tmp/reg.local_machine" +#define SAVE_USERS "/tmp/reg.users" + +static KEYSTRUCT *key_classes_root=NULL; /* windows global values */ +static KEYSTRUCT *key_current_user=NULL; /* user specific values */ +static KEYSTRUCT *key_local_machine=NULL;/* machine specific values */ +static KEYSTRUCT *key_users=NULL; /* all users? */ + +/* dynamic, not saved */ +static KEYSTRUCT *key_performance_data=NULL; +static KEYSTRUCT *key_current_config=NULL; +static KEYSTRUCT *key_dyn_data=NULL; + +/* what valuetypes do we need to convert? */ +#define UNICONVMASK ((1<"; + if (sub!=0 && sub!=1) + return ""; + if (unicodedebug[sub]) free(unicodedebug[sub]); + unicodedebug[sub] = strdupW2A(x); + return unicodedebug[sub]; +} + +static LPKEYSTRUCT +lookup_hkey(HKEY hkey) { + switch (hkey) { + case 0x00000000: + case 0x00000001: + case HKEY_CLASSES_ROOT: + return key_classes_root; + case HKEY_CURRENT_USER: + return key_current_user; + case HKEY_LOCAL_MACHINE: + return key_local_machine; + case HKEY_USERS: + return key_users; + case HKEY_PERFORMANCE_DATA: + return key_performance_data; + case HKEY_DYN_DATA: + return key_dyn_data; + case HKEY_CURRENT_CONFIG: + return key_current_config; + default: + dprintf_reg(stddeb,"lookup_hkey(%lx), special key!\n", + (LONG)hkey + ); + return get_handle(hkey); + } + /*NOTREACHED*/ +} + +/* + * splits the unicode string 'wp' into an array of strings. + * the array is allocated by this function. + * the number of components will be stored in 'wpc' + * Free the array using FREE_KEY_PATH + */ +static void +split_keypath(LPCWSTR wp,LPWSTR **wpv,int *wpc) { + int i,j,len; + LPWSTR ws; + + ws = strdupW(wp); + *wpc = 1; + for (i=0;ws[i];i++) { + if (ws[i]=='\\') { + ws[i]=0; + (*wpc)++; + } + } + len = i; + *wpv = (LPWSTR*)xmalloc(sizeof(LPWSTR)*(*wpc+2)); + (*wpv)[0]= ws; + j = 1; + for (i=1;ikeyname= strdupA2W(""); + + ADD_ROOT_KEY(key_classes_root); + ADD_ROOT_KEY(key_current_user); + ADD_ROOT_KEY(key_local_machine); + ADD_ROOT_KEY(key_users); + ADD_ROOT_KEY(key_performance_data); + ADD_ROOT_KEY(key_current_config); + ADD_ROOT_KEY(key_dyn_data); +#undef ADD_ROOT_KEY +} + +/************************ SAVE Registry Function ****************************/ + +#define REGISTRY_SAVE_VERSION 0x00000001 + +/* Registry saveformat: + * If you change it, increase above number by 1, which will flush + * old registry database files. + * + * Global: + * DWORD version + * DWORD nrofkeys + * KEY keys[nrofkeys] + * + * KEY: + * USTRING name + * USTRING class + * DWORD nrofvalues + * VALUE vals[nrofvalues] + * DWORD nrofsubkeys + * KEY keys[nrofsubkeys] + * + * Value: + * USTRING name + * DWORD type + * DWORD len + * BYTE data[len] + * + * USTRING: + * DWORD len (len==0 means data=NULL) + * BYTE data[len] + * + * + * All _write_XXX and _read_XXX functions return !0 on sucess. + */ + + +static int +_write_DWORD(FILE *F,DWORD dw) { + return fwrite(&dw,sizeof(dw),1,F); +} + +static int +_write_USTRING(FILE *F,LPWSTR str) { + int len; + + if (str==NULL) { + if (!_write_DWORD(F,0)) + return 0; + } else { + len=strlenW(str)*2+2; + + if (!_write_DWORD(F,len)) + return 0; + if (!fwrite(str,len,1,F)) + return 0; + } + return 1; +} + + +static int +_do_save_subkey(FILE *F,LPKEYSTRUCT lpkey) { + LPKEYSTRUCT lpxkey; + int nrofkeys; + int i; + + nrofkeys= 0; + lpxkey = lpkey; + while (lpxkey) { + if (!(lpxkey->flags & REG_OPTION_VOLATILE)) + nrofkeys++; + lpxkey = lpxkey->next; + } + if (!_write_DWORD(F,nrofkeys)) + return 0; + + lpxkey = lpkey; + while (lpxkey) { + if (!(lpxkey->flags & REG_OPTION_VOLATILE)) { + if (!_write_USTRING(F,lpxkey->keyname)) + return 0; + if (!_write_USTRING(F,lpxkey->class)) + return 0; + if (!_write_DWORD(F,lpxkey->nrofvalues)) + return 0; + for (i=0;inrofvalues;i++) { + LPKEYVALUE val=lpxkey->values+i; + + if (!_write_USTRING(F,val->name)) + return 0; + if (!_write_DWORD(F,val->type)) + return 0; + if (!_write_DWORD(F,val->len)) + return 0; + if (!fwrite(val->data,val->len,1,F)) + return 0; + } + /* descend recursively */ + if (!_do_save_subkey(F,lpxkey->nextsub)) + return 0; + } + lpxkey=lpxkey->next; + } + return 1; +} + +static int +_do_savesubreg(FILE *F,LPKEYSTRUCT lpkey) { + if (!_write_DWORD(F,REGISTRY_SAVE_VERSION)) + return 0; + return _do_save_subkey(F,lpkey->nextsub); +} + +static void +_SaveSubReg(LPKEYSTRUCT lpkey,char *fn) { + FILE *F; + + F=fopen(fn,"wb"); + if (F==NULL) { + fprintf(stddeb,__FILE__":_SaveSubReg:Couldn't open %s for writing: %s\n", + fn,strerror(errno) + ); + return; + } + if (!_do_savesubreg(F,lpkey)) { + fclose(F); + unlink(fn); + fprintf(stddeb,__FILE__":_SaveSubReg:Failed to save keys, perhaps no more diskspace for %s?\n",fn); + return; + } + fclose(F); +} + +void +SHELL_SaveRegistry() { + _SaveSubReg(key_classes_root,SAVE_CLASSES_ROOT); + _SaveSubReg(key_current_user,SAVE_CURRENT_USER); + _SaveSubReg(key_local_machine,SAVE_LOCAL_MACHINE); + _SaveSubReg(key_users,SAVE_USERS); +} + +/************************ LOAD Registry Function ****************************/ + +/* FIXME: + * Currently overwrites any old registry data (leaks it away) + * should better be a merge, or ? + */ + +static int +_read_DWORD(FILE *F,DWORD *dw) { + return fread(dw,sizeof(DWORD),1,F); +} + +static int +_read_USTRING(FILE *F,LPWSTR *str) { + DWORD len; + + if (!_read_DWORD(F,&len)) + return 0; + if (len==0) { + *str=NULL; + return 1; + } + *str=xmalloc(len); + return fread(*str,len,1,F); +} + +static int +_do_load_subkey(FILE *F,LPKEYSTRUCT lpkey) { + DWORD howmuch; + LPKEYSTRUCT *lplpkey,lpxkey; + int i; + + if (!_read_DWORD(F,&howmuch)) + return 0; + + /* no subkeys? */ + if (howmuch==0) + return 1; + + lplpkey = &(lpkey->nextsub); + while (howmuch--) { + *lplpkey= (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT)); + memset(*lplpkey,'\0',sizeof(KEYSTRUCT)); + lpxkey = *lplpkey; + if (!_read_USTRING(F,&(lpxkey->keyname))) + return 0; + if (!_read_USTRING(F,&(lpxkey->class))) + return 0; + if (!_read_DWORD(F,&(lpxkey->nrofvalues))) + return 0; + if (lpxkey->nrofvalues) { + lpxkey->values = (LPKEYVALUE)xmalloc( + lpxkey->nrofvalues*sizeof(KEYVALUE) + ); + for (i=0;inrofvalues;i++) { + LPKEYVALUE val=lpxkey->values+i; + + memset(val,'\0',sizeof(KEYVALUE)); + if (!_read_USTRING(F,&(val->name))) + return 0; + if (!_read_DWORD(F,&(val->type))) + return 0; + if (!_read_DWORD(F,&(val->len))) + return 0; + val->data = (LPBYTE)xmalloc(val->len); + if (!fread(val->data,val->len,1,F)) + return 0; + } + } + if (!_do_load_subkey(F,*lplpkey)) + return 0; + lplpkey = &(lpxkey->next); + } + return 1; +} + +static int +_do_loadsubreg(FILE *F,LPKEYSTRUCT lpkey) { + DWORD ver; + + if (!_read_DWORD(F,&ver)) + return 0; + if (ver!=REGISTRY_SAVE_VERSION) { + dprintf_reg(stddeb,__FILE__":_do_loadsubreg:Old format (%lx) registry found, ignoring it.\n",ver); + return 0; + } + if (!_do_load_subkey(F,lpkey)) { + /* FIXME: memory leak on failure to read registry ... + * But this won't happen very often. + */ + lpkey->nextsub=NULL; + return 0; + } + return 1; +} + +static void +_LoadSubReg(LPKEYSTRUCT lpkey,char *fn) { + FILE *F; + + F=fopen(fn,"rb"); + if (F==NULL) { + dprintf_reg(stddeb,__FILE__":Couldn't open %s for reading: %s\n", + fn,strerror(errno) + ); + return; + } + if (!_do_loadsubreg(F,lpkey)) { + fclose(F); + unlink(fn); + } + fclose(F); +} + +void +SHELL_LoadRegistry() { + if (key_classes_root==NULL) + SHELL_Init(); + _LoadSubReg(key_classes_root,SAVE_CLASSES_ROOT); + _LoadSubReg(key_current_user,SAVE_CURRENT_USER); + _LoadSubReg(key_local_machine,SAVE_LOCAL_MACHINE); + _LoadSubReg(key_users,SAVE_USERS); +} + +/********************* API FUNCTIONS ***************************************/ + +/* + * Open Keys. + * + * All functions are stubs to RegOpenKeyExW where all the + * magic happens. + * + * FIXME: security,options,desiredaccess,... + * + * Callpath: + * RegOpenKey -> RegOpenKeyA -> RegOpenKeyExA \ + * RegOpenKeyW -> RegOpenKeyExW + */ + +/* RegOpenKeyExW [ADVAPI32.150] */ +WINAPI DWORD +RegOpenKeyExW( + HKEY hkey, + LPCWSTR lpszSubKey, + DWORD dwReserved, + REGSAM samDesired, + LPHKEY retkey +) { + LPKEYSTRUCT lpNextKey,lpxkey; + LPWSTR *wps; + int wpc,i; + dprintf_reg(stddeb,"RegOpenKeyExW(%lx,%s,%ld,%lx,%p)\n", + (LONG)hkey,W2C(lpszSubKey,0),dwReserved,samDesired,retkey + ); + + lpNextKey = lookup_hkey(hkey); + if (!lpNextKey) + return SHELL_ERROR_BADKEY; + if (!lpszSubKey || !*lpszSubKey) { + add_handle(++currenthandle,lpNextKey,samDesired); + *retkey=currenthandle; + return SHELL_ERROR_SUCCESS; + } + split_keypath(lpszSubKey,&wps,&wpc); + i = 0; + lpxkey = lpNextKey; + while (inextsub; + while (lpxkey) { + if (!strcmpW(wps[i],lpxkey->keyname)) + break; + lpxkey=lpxkey->next; + } + if (!lpxkey) { + FREE_KEY_PATH; + return SHELL_ERROR_BADKEY; + } + i++; + lpNextKey = lpxkey; + } + add_handle(++currenthandle,lpxkey,samDesired); + *retkey = currenthandle; + FREE_KEY_PATH; + return SHELL_ERROR_SUCCESS; +} + +/* RegOpenKeyW [ADVAPI32.151] */ +WINAPI DWORD +RegOpenKeyW( + HKEY hkey, + LPCWSTR lpszSubKey, + LPHKEY retkey +) { + dprintf_reg(stddeb,"RegOpenKeyW(%lx,%s,%p)\n", + (LONG)hkey,W2C(lpszSubKey,0),retkey + ); + return RegOpenKeyExW(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey); +} + + +/* RegOpenKeyExA [ADVAPI32.149] */ +WINAPI DWORD +RegOpenKeyExA( + HKEY hkey, + LPCSTR lpszSubKey, + DWORD dwReserved, + REGSAM samDesired, + LPHKEY retkey +) { + LPWSTR lpszSubKeyW; + DWORD ret; + + dprintf_reg(stddeb,"RegOpenKeyExA(%lx,%s,%ld,%lx,%p)\n", + (LONG)hkey,lpszSubKey,dwReserved,samDesired,retkey + ); + if (lpszSubKey) + lpszSubKeyW=strdupA2W(lpszSubKey); + else + lpszSubKeyW=NULL; + ret=RegOpenKeyExW(hkey,lpszSubKeyW,dwReserved,samDesired,retkey); + if (lpszSubKeyW) + free(lpszSubKeyW); + return ret; +} + +/* RegOpenKeyA [ADVAPI32.148] */ +WINAPI DWORD +RegOpenKeyA( + HKEY hkey, + LPCSTR lpszSubKey, + LPHKEY retkey +) { + dprintf_reg(stddeb,"RegOpenKeyA(%lx,%s,%p)\n", + (LONG)hkey,lpszSubKey,retkey + ); + return RegOpenKeyExA(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey); +} + +/* RegOpenKey [SHELL.1] [KERNEL.217] */ +WINAPI DWORD +RegOpenKey( + HKEY hkey, + LPCSTR lpszSubKey, + LPHKEY retkey +) { + dprintf_reg(stddeb,"RegOpenKey(%lx,%s,%p)\n", + (LONG)hkey,lpszSubKey,retkey + ); + return RegOpenKeyA(hkey,lpszSubKey,retkey); +} + +/* + * Create keys + * + * All those functions convert their respective + * arguments and call RegCreateKeyExW at the end. + * + * FIXME: no security,no access attrib,no optionhandling yet. + * + * Callpath: + * RegCreateKey -> RegCreateKeyA -> RegCreateKeyExA \ + * RegCreateKeyW -> RegCreateKeyExW + */ + +/* RegCreateKeyExW [ADVAPI32.131] */ +WINAPI DWORD +RegCreateKeyExW( + HKEY hkey, + LPCWSTR lpszSubKey, + DWORD dwReserved, + LPWSTR lpszClass, + DWORD fdwOptions, + REGSAM samDesired, + LPSECURITY_ATTRIBUTES lpSecAttribs, + LPHKEY retkey, + LPDWORD lpDispos +) { + LPKEYSTRUCT *lplpPrevKey,lpNextKey,lpxkey; + LPWSTR *wps; + int wpc,i; + +/*FIXME: handle security/access/whatever */ + dprintf_reg(stddeb,"RegCreateKeyExW(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", + (LONG)hkey, + W2C(lpszSubKey,0), + dwReserved, + W2C(lpszClass,1), + fdwOptions, + samDesired, + lpSecAttribs, + retkey, + lpDispos + ); + + lpNextKey = lookup_hkey(hkey); + if (!lpNextKey) + return SHELL_ERROR_BADKEY; + if (!lpszSubKey || !*lpszSubKey) { + add_handle(++currenthandle,lpNextKey,samDesired); + *retkey=currenthandle; + return SHELL_ERROR_SUCCESS; + } + split_keypath(lpszSubKey,&wps,&wpc); + i = 0; + lpxkey = lpNextKey; + while (inextsub; + while (lpxkey) { + if (!strcmpW(wps[i],lpxkey->keyname)) + break; + lpxkey=lpxkey->next; + } + if (!lpxkey) + break; + i++; + lpNextKey = lpxkey; + } + if (lpxkey) { + add_handle(++currenthandle,lpxkey,samDesired); + *retkey = currenthandle; + *lpDispos = REG_OPENED_EXISTING_KEY; + FREE_KEY_PATH; + return SHELL_ERROR_SUCCESS; + } + /* good. now the hard part */ + while (inextsub); + lpxkey = *lplpPrevKey; + while (lpxkey) { + lplpPrevKey = &(lpxkey->next); + lpxkey = *lplpPrevKey; + } + *lplpPrevKey=malloc(sizeof(KEYSTRUCT)); + if (!*lplpPrevKey) { + FREE_KEY_PATH; + return SHELL_ERROR_OUTOFMEMORY; + } + memset(*lplpPrevKey,'\0',sizeof(KEYSTRUCT)); + (*lplpPrevKey)->keyname = strdupW(wps[i]); + (*lplpPrevKey)->next = NULL; + (*lplpPrevKey)->nextsub = NULL; + (*lplpPrevKey)->values = NULL; + (*lplpPrevKey)->nrofvalues = 0; + if (lpszClass) + (*lplpPrevKey)->class = strdupW(lpszClass); + else + (*lplpPrevKey)->class = NULL; + lpNextKey = *lplpPrevKey; + i++; + } + add_handle(++currenthandle,lpNextKey,samDesired); + + /*FIXME: flag handling correct? */ + lpNextKey->flags= fdwOptions; + if (lpszClass) + lpNextKey->class = strdupW(lpszClass); + else + lpNextKey->class = NULL; + *retkey = currenthandle; + *lpDispos = REG_CREATED_NEW_KEY; + FREE_KEY_PATH; + return SHELL_ERROR_SUCCESS; +} + +/* RegCreateKeyW [ADVAPI32.132] */ +WINAPI DWORD +RegCreateKeyW( + HKEY hkey, + LPCWSTR lpszSubKey, + LPHKEY retkey +) { + DWORD junk,ret; + + dprintf_reg(stddeb,"RegCreateKeyW(%lx,%s,%p)\n", + (LONG)hkey,W2C(lpszSubKey,0),retkey + ); + ret=RegCreateKeyExW( + hkey, /* key handle */ + lpszSubKey, /* subkey name */ + 0, /* reserved = 0 */ + NULL, /* lpszClass? FIXME: ? */ + REG_OPTION_NON_VOLATILE, /* options */ + KEY_ALL_ACCESS, /* desired access attribs */ + NULL, /* lpsecurity attributes */ + retkey, /* lpretkey */ + &junk /* disposition value */ + ); + return ret; +} + +/* RegCreateKeyExA [ADVAPI32.130] */ +WINAPI DWORD +RegCreateKeyExA( + HKEY hkey, + LPCSTR lpszSubKey, + DWORD dwReserved, + LPSTR lpszClass, + DWORD fdwOptions, + REGSAM samDesired, + LPSECURITY_ATTRIBUTES lpSecAttribs, + LPHKEY retkey, + LPDWORD lpDispos +) { + LPWSTR lpszSubKeyW,lpszClassW; + DWORD ret; + + dprintf_reg(stddeb,"RegCreateKeyExA(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", + (LONG)hkey, + lpszSubKey, + dwReserved, + lpszClass, + fdwOptions, + samDesired, + lpSecAttribs, + retkey, + lpDispos + ); + if (lpszSubKey) + lpszSubKeyW=strdupA2W(lpszSubKey); + else + lpszSubKeyW=NULL; + if (lpszClass) + lpszClassW=strdupA2W(lpszClass); + else + lpszClassW=NULL; + ret=RegCreateKeyExW( + hkey, + lpszSubKeyW, + dwReserved, + lpszClassW, + fdwOptions, + samDesired, + lpSecAttribs, + retkey, + lpDispos + ); + if (lpszSubKeyW) + free(lpszSubKeyW); + if (lpszClassW) + free(lpszClassW); + return ret; +} + +/* RegCreateKeyA [ADVAPI32.129] */ +WINAPI DWORD +RegCreateKeyA( + HKEY hkey, + LPCSTR lpszSubKey, + LPHKEY retkey +) { + DWORD junk; + + dprintf_reg(stddeb,"RegCreateKeyA(%lx,%s,%p)\n", + (LONG)hkey,lpszSubKey,retkey + ); + return RegCreateKeyExA( + hkey, /* key handle */ + lpszSubKey, /* subkey name */ + 0, /* reserved = 0 */ + NULL, /* lpszClass? FIXME: ? */ + REG_OPTION_NON_VOLATILE,/* options */ + KEY_ALL_ACCESS, /* desired access attribs */ + NULL, /* lpsecurity attributes */ + retkey, /* lpretkey */ + &junk /* disposition value */ + ); +} + +/* RegCreateKey [SHELL.2] [KERNEL.218] */ +WINAPI DWORD +RegCreateKey( + HKEY hkey, + LPCSTR lpszSubKey, + LPHKEY retkey +) { + dprintf_reg(stddeb,"RegCreateKey(%lx,%s,%p)\n", + (LONG)hkey,lpszSubKey,retkey + ); + return RegCreateKeyA(hkey,lpszSubKey,retkey); +} + +/* + * Query Value Functions + * Win32 differs between keynames and valuenames. + * multiple values may belong to one key, the special value + * with name NULL is the default value used by the win31 + * compat functions. + * + * Callpath: + * RegQueryValue -> RegQueryValueA -> RegQueryValueExA \ + * RegQueryValueW -> RegQueryValueExW + */ + +/* RegQueryValueExW [ADVAPI32.158] */ +WINAPI DWORD +RegQueryValueExW( + HKEY hkey, + LPWSTR lpszValueName, + LPDWORD lpdwReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + LPKEYSTRUCT lpkey; + int i; + + dprintf_reg(stddeb,"RegQueryValueExW(%lx,%s,%p,%p,%p,%p)\n", + hkey,W2C(lpszValueName,0),lpdwReserved,lpdwType,lpbData,lpcbData + ); + + lpkey = lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (lpszValueName==NULL) { + for (i=0;inrofvalues;i++) + if (lpkey->values[i].name==NULL) + break; + } else { + for (i=0;inrofvalues;i++) + if (!strcmpW(lpszValueName,lpkey->values[i].name)) + break; + } + if (i==lpkey->nrofvalues) { + if (lpszValueName==NULL) { + *(WCHAR*)lpbData = 0; + *lpcbData = 2; + *lpdwType = REG_SZ; + return SHELL_ERROR_SUCCESS; + } + return SHELL_ERROR_BADKEY;/*FIXME: correct return? */ + } + if (lpdwType) + *lpdwType = lpkey->values[i].type; + if (lpbData==NULL) { + if (lpcbData==NULL) + return SHELL_ERROR_SUCCESS; + *lpcbData = lpkey->values[i].len; + return SHELL_ERROR_SUCCESS; + } + if (*lpcbDatavalues[i].len) { + *(WCHAR*)lpbData + = 0; + *lpcbData = lpkey->values[i].len; + return ERROR_MORE_DATA; + } + memcpy(lpbData,lpkey->values[i].data,lpkey->values[i].len); + *lpcbData = lpkey->values[i].len; + return SHELL_ERROR_SUCCESS; +} + +/* RegQueryValueW [ADVAPI32.159] */ +WINAPI DWORD +RegQueryValueW( + HKEY hkey, + LPWSTR lpszSubKey, + LPWSTR lpszData, + LPDWORD lpcbData +) { + HKEY xhkey; + DWORD ret,lpdwType; + + dprintf_reg(stddeb,"RegQueryValueW(%lx,%s,%p,%p)\n->", + hkey,W2C(lpszSubKey,0),lpszData,lpcbData + ); + + /* only open subkey, if we really do descend */ + if (lpszSubKey && *lpszSubKey) { + ret = RegOpenKeyW(hkey,lpszSubKey,&xhkey); + if (ret!=ERROR_SUCCESS) + return ret; + } else + xhkey = hkey; + + lpdwType = REG_SZ; + ret = RegQueryValueExW( + xhkey, + NULL, /* varname NULL -> compat */ + NULL, /* lpdwReserved, must be NULL */ + &lpdwType, + (LPBYTE)lpszData, + lpcbData + ); + if (xhkey!=hkey) + RegCloseKey(xhkey); + return ret; +} + +/* RegQueryValueExA [ADVAPI32.157] */ +WINAPI DWORD +RegQueryValueExA( + HKEY hkey, + LPSTR lpszValueName, + LPDWORD lpdwReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + LPWSTR lpszValueNameW; + LPBYTE buf; + DWORD ret,myxlen; + DWORD *mylen; + + dprintf_reg(stddeb,"RegQueryValueExA(%lx,%s,%p,%p,%p,%p)\n->", + hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,lpcbData + ); + if (lpbData) { + /* double buffer */ + buf = (LPBYTE)xmalloc((*lpcbData)*2); + myxlen = *lpcbData*2; + mylen = &myxlen; + } else { + buf=NULL; + if (lpcbData) { + myxlen = *lpcbData*2; + mylen = &myxlen; + } + mylen = NULL; + } + if (lpszValueName) + lpszValueNameW=strdupA2W(lpszValueName); + else + lpszValueNameW=NULL; + + ret=RegQueryValueExW( + hkey, + lpszValueNameW, + lpdwReserved, + lpdwType, + buf, + mylen + ); + + if (ret==ERROR_SUCCESS) { + if (buf) { + if (UNICONVMASK & (1<<(*lpdwType))) { + /* convert UNICODE to ASCII */ + strcpyWA(lpbData,(LPWSTR)buf); + *lpcbData = myxlen/2; + } else { + if (myxlen>*lpcbData) + ret = ERROR_MORE_DATA; + else + memcpy(lpbData,buf,myxlen); + + *lpcbData = myxlen; + } + } else { + if ((UNICONVMASK & (1<<(*lpdwType))) && lpcbData) + *lpcbData = myxlen/2; + } + } else { + if ((UNICONVMASK & (1<<(*lpdwType))) && lpcbData) + *lpcbData = myxlen/2; + } + if (buf) + free(buf); + return ret; +} + +/* RegQueryValueEx [KERNEL.225] */ +WINAPI DWORD +RegQueryValueEx( + HKEY hkey, + LPSTR lpszValueName, + LPDWORD lpdwReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + dprintf_reg(stddeb,"RegQueryValueEx(%lx,%s,%p,%p,%p,%p)\n", + hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,lpcbData + ); + return RegQueryValueExA( + hkey, + lpszValueName, + lpdwReserved, + lpdwType, + lpbData, + lpcbData + ); +} + +/* RegQueryValueA [ADVAPI32.156] */ +WINAPI DWORD +RegQueryValueA( + HKEY hkey, + LPSTR lpszSubKey, + LPSTR lpszData, + LPDWORD lpcbData +) { + HKEY xhkey; + DWORD ret,lpdwType; + + dprintf_reg(stddeb,"RegQueryValueA(%lx,%s,%p,%p)\n", + hkey,lpszSubKey,lpszData,lpcbData + ); + + /* only open subkey, if we really do descend */ + if (lpszSubKey && *lpszSubKey) { + ret = RegOpenKey(hkey,lpszSubKey,&xhkey); + if (ret!=ERROR_SUCCESS) + return ret; + } else + xhkey = hkey; + + lpdwType = REG_SZ; + ret = RegQueryValueExA( + xhkey, + NULL, /* lpszValueName NULL -> compat */ + NULL, /* lpdwReserved, must be NULL */ + &lpdwType, + (LPBYTE)lpszData, + lpcbData + ); + if (xhkey!=hkey) + RegCloseKey(xhkey); + return ret; +} + +/* RegQueryValue [SHELL.6] [KERNEL.224] */ +WINAPI DWORD +RegQueryValue( + HKEY hkey, + LPSTR lpszSubKey, + LPSTR lpszData, + LPDWORD lpcbData +) { + dprintf_reg(stddeb,"RegQueryValueA(%lx,%s,%p,%p)\n", + hkey,lpszSubKey,lpszData,lpcbData + ); + return RegQueryValueA(hkey,lpszSubKey,lpszData,lpcbData); +} + +/* + * Setting values of Registry keys + * + * Callpath: + * RegSetValue -> RegSetValueA -> RegSetValueExA \ + * RegSetValueW -> RegSetValueExW + */ + +/* RegSetValueExW [ADVAPI32.170] */ +WINAPI DWORD +RegSetValueExW( + HKEY hkey, + LPWSTR lpszValueName, + DWORD dwReserved, + DWORD dwType, + LPBYTE lpbData, + DWORD cbData +) { + LPKEYSTRUCT lpkey; + int i; + + dprintf_reg(stddeb,"RegSetValueExW(%lx,%s,%ld,%ld,%p,%ld)\n", + hkey,W2C(lpszValueName,0),dwReserved,dwType,lpbData,cbData + ); + /* we no longer care about the lpbData dwType here... */ + lpkey = lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (lpszValueName==NULL) { + for (i=0;inrofvalues;i++) + if (lpkey->values[i].name==NULL) + break; + } else { + for (i=0;inrofvalues;i++) + if (!strcmpW(lpszValueName,lpkey->values[i].name)) + break; + } + if (i==lpkey->nrofvalues) { + lpkey->values = (LPKEYVALUE)xrealloc( + lpkey->values, + (lpkey->nrofvalues+1)*sizeof(KEYVALUE) + ); + lpkey->nrofvalues++; + memset(lpkey->values+i,'\0',sizeof(KEYVALUE)); + } + if (lpkey->values[i].name==NULL) + if (lpszValueName) + lpkey->values[i].name = strdupW(lpszValueName); + else + lpkey->values[i].name = NULL; + lpkey->values[i].len = cbData; + lpkey->values[i].type = dwType; + if (lpkey->values[i].data !=NULL) + free(lpkey->values[i].data); + lpkey->values[i].data = (LPBYTE)xmalloc(cbData); + memcpy(lpkey->values[i].data,lpbData,cbData); + return SHELL_ERROR_SUCCESS; +} + +/* RegSetValueExA [ADVAPI32.169] */ +WINAPI DWORD +RegSetValueExA( + HKEY hkey, + LPSTR lpszValueName, + DWORD dwReserved, + DWORD dwType, + LPBYTE lpbData, + DWORD cbData +) { + LPBYTE buf; + LPWSTR lpszValueNameW; + DWORD ret; + + dprintf_reg(stddeb,"RegSetValueExA(%lx,%s,%ld,%ld,%p,%ld)\n->", + hkey,lpszValueName,dwReserved,dwType,lpbData,cbData + ); + if ((1<", + hkey,lpszValueName,dwReserved,dwType,lpbData,cbData + ); + return RegSetValueExA(hkey,lpszValueName,dwReserved,dwType,lpbData,cbData); +} + +/* RegSetValueW [ADVAPI32.171] */ +WINAPI DWORD +RegSetValueW( + HKEY hkey, + LPCWSTR lpszSubKey, + DWORD dwType, + LPCWSTR lpszData, + DWORD cbData +) { + HKEY xhkey; + DWORD ret; + + dprintf_reg(stddeb,"RegSetValueW(%lx,%s,%ld,%s,%ld)\n->", + hkey,W2C(lpszSubKey,0),dwType,W2C(lpszData,0),cbData + ); + if (lpszSubKey && *lpszSubKey) { + ret=RegCreateKeyW(hkey,lpszSubKey,&xhkey); + if (ret!=ERROR_SUCCESS) + return ret; + } else + xhkey=hkey; + if (dwType!=REG_SZ) { + fprintf(stddeb,"RegSetValueX called with dwType=%ld!\n",dwType); + dwType=REG_SZ; + } + if (cbData!=2*strlenW(lpszData)+2) { + dprintf_reg(stddeb,"RegSetValueX called with len=%ld != strlen(%s)+1=%d!\n", + cbData,W2C(lpszData,0),2*strlenW(lpszData)+2 + ); + cbData=2*strlenW(lpszData)+2; + } + ret=RegSetValueExW(xhkey,NULL,0,dwType,(LPBYTE)lpszData,cbData); + if (hkey!=xhkey) + RegCloseKey(xhkey); + return ret; + +} +/* RegSetValueA [ADVAPI32.168] */ +WINAPI DWORD +RegSetValueA( + HKEY hkey, + LPCSTR lpszSubKey, + DWORD dwType, + LPCSTR lpszData, + DWORD cbData +) { + DWORD ret; + HKEY xhkey; + + dprintf_reg(stddeb,"RegSetValueA(%lx,%s,%ld,%s,%ld)\n->", + hkey,lpszSubKey,dwType,lpszData,cbData + ); + if (lpszSubKey && *lpszSubKey) { + ret=RegCreateKey(hkey,lpszSubKey,&xhkey); + if (ret!=ERROR_SUCCESS) + return ret; + } else + xhkey=hkey; + + if (dwType!=REG_SZ) { + dprintf_reg(stddeb,"RegSetValueA called with dwType=%ld!\n",dwType); + dwType=REG_SZ; + } + if (cbData!=strlen(lpszData)+1) + cbData=strlen(lpszData)+1; + ret=RegSetValueExA(xhkey,NULL,0,dwType,(LPBYTE)lpszData,cbData); + if (xhkey!=hkey) + RegCloseKey(xhkey); + return ret; +} + +/* RegSetValue [KERNEL.221] [SHELL.5] */ +WINAPI DWORD +RegSetValue( + HKEY hkey, + LPCSTR lpszSubKey, + DWORD dwType, + LPCSTR lpszData, + DWORD cbData +) { + DWORD ret; + dprintf_reg(stddeb,"RegSetValue(%lx,%s,%ld,%s,%ld)\n->", + hkey,lpszSubKey,dwType,lpszData,cbData + ); + ret=RegSetValueA(hkey,lpszSubKey,dwType,lpszData,cbData); + return ret; +} + +/* + * Key Enumeration + * + * Callpath: + * RegEnumKey -> RegEnumKeyA -> RegEnumKeyExA \ + * RegEnumKeyW -> RegEnumKeyExW + */ + +/* RegEnumKeyExW [ADVAPI32.139] */ +WINAPI DWORD +RegEnumKeyExW( + HKEY hkey, + DWORD iSubkey, + LPWSTR lpszName, + LPDWORD lpcchName, + LPDWORD lpdwReserved, + LPWSTR lpszClass, + LPDWORD lpcchClass, + FILETIME *ft +) { + LPKEYSTRUCT lpkey,lpxkey; + + dprintf_reg(stddeb,"RegEnumKeyExW(%lx,%ld,%p,%ld,%p,%p,%p,%p)\n", + hkey,iSubkey,lpszName,*lpcchName,lpdwReserved,lpszClass,lpcchClass,ft + ); + lpkey=lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (!lpkey->nextsub) + return ERROR_NO_MORE_ITEMS; + lpxkey=lpkey->nextsub; + while (iSubkey && lpxkey) { + iSubkey--; + lpxkey=lpxkey->next; + } + if (iSubkey || !lpxkey) + return ERROR_NO_MORE_ITEMS; + if (2*strlenW(lpxkey->keyname)+2>*lpcchName) + return ERROR_MORE_DATA; + memcpy(lpszName,lpxkey->keyname,strlenW(lpxkey->keyname)*2+2); + if (lpszClass) { + /* what should we write into it? */ + *lpszClass = 0; + *lpcchClass = 2; + } + return ERROR_SUCCESS; + +} + +/* RegEnumKeyW [ADVAPI32.140] */ +WINAPI DWORD +RegEnumKeyW( + HKEY hkey, + DWORD iSubkey, + LPWSTR lpszName, + DWORD lpcchName +) { + FILETIME ft; + + dprintf_reg(stddeb,"RegEnumKeyW(%lx,%ld,%p,%ld)\n->", + hkey,iSubkey,lpszName,lpcchName + ); + return RegEnumKeyExW(hkey,iSubkey,lpszName,&lpcchName,NULL,NULL,NULL,&ft); +} +/* RegEnumKeyExA [ADVAPI32.138] */ +WINAPI DWORD +RegEnumKeyExA( + HKEY hkey, + DWORD iSubkey, + LPSTR lpszName, + LPDWORD lpcchName, + LPDWORD lpdwReserved, + LPSTR lpszClass, + LPDWORD lpcchClass, + FILETIME *ft +) { + DWORD ret,lpcchNameW,lpcchClassW; + LPWSTR lpszNameW,lpszClassW; + + + dprintf_reg(stddeb,"RegEnumKeyExA(%lx,%ld,%p,%ld,%p,%p,%p,%p)\n->", + hkey,iSubkey,lpszName,*lpcchName,lpdwReserved,lpszClass,lpcchClass,ft + ); + if (lpszName) { + lpszNameW = (LPWSTR)xmalloc(*lpcchName*2); + lpcchNameW = *lpcchName*2; + } else { + lpszNameW = NULL; + lpcchNameW = 0; + } + if (lpszClass) { + lpszClassW = (LPWSTR)xmalloc(*lpcchClass*2); + lpcchClassW = *lpcchClass*2; + } else { + lpszClassW =0; + lpcchClassW=0; + } + ret=RegEnumKeyExW( + hkey, + iSubkey, + lpszNameW, + &lpcchNameW, + lpdwReserved, + lpszClassW, + &lpcchClassW, + ft + ); + if (ret==ERROR_SUCCESS) { + strcpyWA(lpszName,lpszNameW); + *lpcchName=strlen(lpszName); + if (lpszClassW) { + strcpyWA(lpszClass,lpszClassW); + *lpcchClass=strlen(lpszClass); + } + } + if (lpszNameW) + free(lpszNameW); + if (lpszClassW) + free(lpszClassW); + return ret; +} + +/* RegEnumKeyA [ADVAPI32.137] */ +WINAPI DWORD +RegEnumKeyA( + HKEY hkey, + DWORD iSubkey, + LPSTR lpszName, + DWORD lpcchName +) { + FILETIME ft; + + dprintf_reg(stddeb,"RegEnumKeyA(%lx,%ld,%p,%ld)\n->", + hkey,iSubkey,lpszName,lpcchName + ); + return RegEnumKeyExA( + hkey, + iSubkey, + lpszName, + &lpcchName, + NULL, + NULL, + NULL, + &ft + ); +} + +/* RegEnumKey [SHELL.7] [KERNEL.216] */ +WINAPI DWORD +RegEnumKey( + HKEY hkey, + DWORD iSubkey, + LPSTR lpszName, + DWORD lpcchName +) { + dprintf_reg(stddeb,"RegEnumKey(%lx,%ld,%p,%ld)\n->", + hkey,iSubkey,lpszName,lpcchName + ); + return RegEnumKeyA(hkey,iSubkey,lpszName,lpcchName); +} + +/* + * Enumerate Registry Values + * + * Callpath: + * RegEnumValue -> RegEnumValueA -> RegEnumValueW + */ + +/* RegEnumValueW [ADVAPI32.142] */ +WINAPI DWORD +RegEnumValueW( + HKEY hkey, + DWORD iValue, + LPWSTR lpszValue, + LPDWORD lpcchValue, + LPDWORD lpdReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + LPKEYSTRUCT lpkey; + LPKEYVALUE val; + + dprintf_reg(stddeb,"RegEnumValueW(%ld,%ld,%p,%p,%p,%p,%p,%p)\n", + hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData + ); + lpkey = lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (lpkey->nrofvaluesvalues+iValue; + + if (val->name) { + if (strlenW(val->name)*2+2>*lpcchValue) { + *lpcchValue = strlenW(val->name)*2+2; + return ERROR_MORE_DATA; + } + memcpy(lpszValue,val->name,2*strlenW(val->name)+2); + *lpcchValue=strlenW(val->name)*2+2; + } else { + /* how to handle NULL value? */ + *lpszValue = 0; + *lpcchValue = 2; + } + *lpdwType=val->type; + if (lpbData) { + if (val->len>*lpcbData) + return ERROR_MORE_DATA; + memcpy(lpbData,val->data,val->len); + *lpcbData = val->len; + } + return SHELL_ERROR_SUCCESS; +} + +/* RegEnumValueA [ADVAPI32.141] */ +WINAPI DWORD +RegEnumValueA( + HKEY hkey, + DWORD iValue, + LPSTR lpszValue, + LPDWORD lpcchValue, + LPDWORD lpdReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + LPWSTR lpszValueW; + LPBYTE lpbDataW; + DWORD ret,lpcbDataW; + + dprintf_reg(stddeb,"RegEnumValueA(%ld,%ld,%p,%p,%p,%p,%p,%p)\n", + hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData + ); + + lpszValueW = (LPWSTR)xmalloc(*lpcchValue*2); + if (lpbData) { + lpbDataW = (LPBYTE)xmalloc(*lpcbData*2); + lpcbDataW = *lpcbData*2; + } else + lpbDataW = NULL; + ret=RegEnumValueW( + hkey, + iValue, + lpszValueW, + lpcchValue, + lpdReserved, + lpdwType, + lpbDataW, + &lpcbDataW + ); + + if (ret==ERROR_SUCCESS) { + strcpyWA(lpszValue,lpszValueW); + if (lpbData) { + if ((1<<*lpdwType) & UNICONVMASK) { + strcpyWA(lpbData,(LPWSTR)lpbDataW); + } else { + if (lpcbDataW > *lpcbData) + ret = ERROR_MORE_DATA; + else + memcpy(lpbData,lpbDataW,lpcbDataW); + } + *lpcbData = lpcbDataW; + } + } + if (lpbDataW) + free(lpbDataW); + if (lpszValueW) + free(lpszValueW); + return ret; +} + +/* RegEnumValue [KERNEL.223] */ +WINAPI DWORD +RegEnumValue( + HKEY hkey, + DWORD iValue, + LPSTR lpszValue, + LPDWORD lpcchValue, + LPDWORD lpdReserved, + LPDWORD lpdwType, + LPBYTE lpbData, + LPDWORD lpcbData +) { + dprintf_reg(stddeb,"RegEnumValue(%ld,%ld,%p,%p,%p,%p,%p,%p)\n", + hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData + ); + return RegEnumValueA( + hkey, + iValue, + lpszValue, + lpcchValue, + lpdReserved, + lpdwType, + lpbData, + lpcbData + ); +} + +/* + * Close registry key + */ +/* RegCloseKey [SHELL.3] [KERNEL.220] [ADVAPI32.126] */ +WINAPI DWORD +RegCloseKey(HKEY hkey) { + dprintf_reg(stddeb,"RegCloseKey(%ld)\n",hkey); + remove_handle(hkey); + return ERROR_SUCCESS; +} +/* + * Delete registry key + * + * Callpath: + * RegDeleteKey -> RegDeleteKeyA -> RegDeleteKeyW + */ +/* RegDeleteKeyW [ADVAPI32.134] */ +WINAPI DWORD +RegDeleteKeyW(HKEY hkey,LPWSTR lpszSubKey) { + LPKEYSTRUCT *lplpPrevKey,lpNextKey,lpxkey; + LPWSTR *wps; + int wpc,i; + + dprintf_reg(stddeb,"RegDeleteKeyW(%ld,%s)\n", + hkey,W2C(lpszSubKey,0) + ); + lpNextKey = lookup_hkey(hkey); + if (!lpNextKey) + return SHELL_ERROR_BADKEY; + /* we need to know the previous key in the hier. */ + if (!lpszSubKey || !*lpszSubKey) + return SHELL_ERROR_BADKEY; + split_keypath(lpszSubKey,&wps,&wpc); + i = 0; + lpxkey = lpNextKey; + while (inextsub; + while (lpxkey) { + if (!strcmpW(wps[i],lpxkey->keyname)) + break; + lpxkey=lpxkey->next; + } + if (!lpxkey) { + FREE_KEY_PATH; + /* not found is success */ + return SHELL_ERROR_SUCCESS; + } + i++; + lpNextKey = lpxkey; + } + lpxkey = lpNextKey->nextsub; + lplpPrevKey = &(lpNextKey->nextsub); + while (lpxkey) { + if (!strcmpW(wps[i],lpxkey->keyname)) + break; + lplpPrevKey = &(lpxkey->next); + lpxkey = lpxkey->next; + } + if (!lpxkey) + return SHELL_ERROR_SUCCESS; + if (lpxkey->nextsub) + return SHELL_ERROR_CANTWRITE; + *lplpPrevKey = lpxkey->next; + free(lpxkey->keyname); + if (lpxkey->class) + free(lpxkey->class); + if (lpxkey->values) + free(lpxkey->values); + free(lpxkey); + FREE_KEY_PATH; + return SHELL_ERROR_SUCCESS; +} + +/* RegDeleteKeyA [ADVAPI32.133] */ +WINAPI DWORD +RegDeleteKeyA(HKEY hkey,LPCSTR lpszSubKey) { + LPWSTR lpszSubKeyW; + DWORD ret; + + dprintf_reg(stddeb,"RegDeleteKeyA(%ld,%s)\n", + hkey,lpszSubKey + ); + lpszSubKeyW=strdupA2W(lpszSubKey); + ret=RegDeleteKeyW(hkey,lpszSubKeyW); + free(lpszSubKeyW); + return ret; +} + +/* RegDeleteKey [SHELL.4] [KERNEL.219] */ +WINAPI DWORD +RegDeleteKey(HKEY hkey,LPCSTR lpszSubKey) { + dprintf_reg(stddeb,"RegDeleteKey(%ld,%s)\n", + hkey,lpszSubKey + ); + return RegDeleteKeyA(hkey,lpszSubKey); +} + +/* + * Delete registry value + * + * Callpath: + * RegDeleteValue -> RegDeleteValueA -> RegDeleteValueW + */ +/* RegDeleteValueW [ADVAPI32.136] */ +WINAPI DWORD +RegDeleteValueW(HKEY hkey,LPWSTR lpszValue) { + DWORD i; + LPKEYSTRUCT lpkey; + LPKEYVALUE val; + + dprintf_reg(stddeb,"RegDeleteValueW(%ld,%s)\n", + hkey,W2C(lpszValue,0) + ); + lpkey=lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (lpszValue) { + for (i=0;inrofvalues;i++) + if (!strcmpW(lpkey->values[i].name,lpszValue)) + break; + } else { + for (i=0;inrofvalues;i++) + if (lpkey->values[i].name==NULL) + break; + } + if (i==lpkey->nrofvalues) + return SHELL_ERROR_BADKEY;/*FIXME: correct errorcode? */ + val = lpkey->values+i; + if (val->name) free(val->name); + if (val->data) free(val->data); + memcpy( + lpkey->values+i, + lpkey->values+i+1, + sizeof(KEYVALUE)*(lpkey->nrofvalues-i-1) + ); + lpkey->values = (LPKEYVALUE)xrealloc( + lpkey->values, + (lpkey->nrofvalues-1)*sizeof(KEYVALUE) + ); + lpkey->nrofvalues--; + return SHELL_ERROR_SUCCESS; +} + +/* RegDeleteValueA [ADVAPI32.135] */ +WINAPI DWORD +RegDeleteValueA(HKEY hkey,LPSTR lpszValue) { + LPWSTR lpszValueW; + DWORD ret; + + dprintf_reg(stddeb,"RegDeleteValueA(%ld,%s)\n", + hkey,lpszValue + ); + if (lpszValue) + lpszValueW=strdupA2W(lpszValue); + else + lpszValueW=NULL; + ret=RegDeleteValueW(hkey,lpszValueW); + if (lpszValueW) + free(lpszValueW); + return ret; +} + +/* RegDeleteValue [KERNEL.222] */ +WINAPI DWORD +RegDeleteValue(HKEY hkey,LPSTR lpszValue) { + dprintf_reg(stddeb,"RegDeleteValue(%ld,%s)\n", + hkey,lpszValue + ); + return RegDeleteValueA(hkey,lpszValue); +} + +/* RegFlushKey [ADVAPI32.143] [KERNEL.227] */ +WINAPI DWORD +RegFlushKey(HKEY hkey) { + dprintf_reg(stddeb,"RegFlushKey(%ld), STUB.\n",hkey); + return SHELL_ERROR_SUCCESS; +} + +/* FIXME: lpcchXXXX ... is this counting in WCHARS or in BYTEs ?? */ + +/* RegQueryInfoKeyW [ADVAPI32.153] */ +WINAPI DWORD +RegQueryInfoKeyW( + HKEY hkey, + LPWSTR lpszClass, + LPDWORD lpcchClass, + LPDWORD lpdwReserved, + LPDWORD lpcSubKeys, + LPDWORD lpcchMaxSubkey, + LPDWORD lpcchMaxClass, + LPDWORD lpcValues, + LPDWORD lpcchMaxValueName, + LPDWORD lpccbMaxValueData, + LPDWORD lpcbSecurityDescriptor, + FILETIME *ft +) { + LPKEYSTRUCT lpkey,lpxkey; + int nrofkeys,maxsubkey,maxclass,maxvalues,maxvname,maxvdata; + int i; + + dprintf_reg(stddeb,"RegQueryInfoKeyW(%lx,......)\n",hkey); + lpkey=lookup_hkey(hkey); + if (!lpkey) + return SHELL_ERROR_BADKEY; + if (lpszClass) { + if (lpkey->class) { + if (strlenW(lpkey->class)*2+2>*lpcchClass) { + *lpcchClass=strlenW(lpkey->class)*2; + return ERROR_MORE_DATA; + } + *lpcchClass=strlenW(lpkey->class)*2; + memcpy(lpszClass,lpkey->class,strlenW(lpkey->class)); + } else { + *lpszClass = 0; + *lpcchClass = 0; + } + } else { + if (lpcchClass) + *lpcchClass = strlenW(lpkey->class)*2; + } + lpxkey=lpkey->nextsub; + nrofkeys=maxsubkey=maxclass=maxvalues=maxvname=maxvdata=0; + while (lpxkey) { + nrofkeys++; + if (strlenW(lpxkey->keyname)>maxsubkey) + maxsubkey=strlenW(lpxkey->keyname); + if (lpxkey->class && strlenW(lpxkey->class)>maxclass) + maxclass=strlenW(lpxkey->class); + if (lpxkey->nrofvalues>maxvalues) + maxvalues=lpxkey->nrofvalues; + for (i=0;inrofvalues;i++) { + LPKEYVALUE val=lpxkey->values+i; + + if (val->name && strlenW(val->name)>maxvname) + maxvname=strlenW(val->name); + if (val->len>maxvdata) + maxvdata=val->len; + } + lpxkey=lpxkey->next; + } + if (!maxclass) maxclass = 1; + if (!maxvname) maxvname = 1; + if (lpcSubKeys) + *lpcSubKeys = nrofkeys; + if (lpcchMaxSubkey) + *lpcchMaxSubkey = maxsubkey*2; + if (lpcchMaxClass) + *lpcchMaxClass = maxclass*2; + if (lpcValues) + *lpcValues = maxvalues; + if (lpcchMaxValueName) + *lpcchMaxValueName= maxvname; + if (lpccbMaxValueData) + *lpccbMaxValueData= maxvdata; + return SHELL_ERROR_SUCCESS; +} + +/* RegQueryInfoKeyA [ADVAPI32.152] */ +WINAPI DWORD +RegQueryInfoKeyA( + HKEY hkey, + LPSTR lpszClass, + LPDWORD lpcchClass, + LPDWORD lpdwReserved, + LPDWORD lpcSubKeys, + LPDWORD lpcchMaxSubkey, + LPDWORD lpcchMaxClass, + LPDWORD lpcValues, + LPDWORD lpcchMaxValueName, + LPDWORD lpccbMaxValueData, + LPDWORD lpcbSecurityDescriptor, + FILETIME *ft +) { + LPWSTR lpszClassW; + DWORD ret; + + dprintf_reg(stddeb,"RegQueryInfoKeyA(%lx,......)\n",hkey); + if (lpszClass) { + *lpcchClass*= 2; + lpszClassW = (LPWSTR)xmalloc(*lpcchClass); + + } else + lpszClassW = NULL; + ret=RegQueryInfoKeyW( + hkey, + lpszClassW, + lpcchClass, + lpdwReserved, + lpcSubKeys, + lpcchMaxSubkey, + lpcchMaxClass, + lpcValues, + lpcchMaxValueName, + lpccbMaxValueData, + lpcbSecurityDescriptor, + ft + ); + if (ret==ERROR_SUCCESS) + strcpyWA(lpszClass,lpszClassW); + if (lpcchClass) + *lpcchClass/=2; + if (lpcchMaxSubkey) + *lpcchMaxSubkey/=2; + if (lpcchMaxClass) + *lpcchMaxClass/=2; + if (lpcchMaxValueName) + *lpcchMaxValueName/=2; + if (lpszClassW) + free(lpszClassW); + return ret; +} diff --git a/misc/shell.c b/misc/shell.c index 12aea21ba6..c2095311cf 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -8,10 +8,8 @@ #include #include "windows.h" #include "shell.h" +#include "module.h" #include "neexe.h" -#include "selectors.h" -#include "alias.h" -#include "relay32.h" #include "resource.h" #include "dlgs.h" #include "win.h" @@ -19,453 +17,6 @@ #include "debug.h" #include "xmalloc.h" -LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL; - -static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]"; - -/************************************************************************* - * SHELL_Init() - */ -BOOL SHELL_Init() -{ - HKEY hNewKey; - - hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); - lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lphRootKey == NULL) { - printf("SHELL_RegCheckForRoot: Couldn't allocate root key!\n"); - return FALSE; - } - lphRootKey->hKey = (HKEY)1; - lphRootKey->lpSubKey = RootKeyName; - lphRootKey->dwType = 0; - lphRootKey->lpValue = NULL; - lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL; - - hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); - lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lphTopKey == NULL) { - printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n"); - return FALSE; - } - lphTopKey->hKey = 0; - lphTopKey->lpSubKey = TopKeyName; - lphTopKey->dwType = 0; - lphTopKey->lpValue = NULL; - lphTopKey->lpSubLvl = lphRootKey; - lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL; - - dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n"); - - return TRUE; -} - -/* FIXME: the loading and saving of the registry database is rather messy. - * bad input (while reading) may crash wine. - */ -void -_DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs) -{ - LPKEYSTRUCT lpKey; - - lpKey=lpTKey->lpSubLvl; - while (lpKey) { - int i; - for (i=0;ilpValue) - fprintf(f,"%s=%s\n",lpKey->lpSubKey,lpKey->lpValue); - else - fprintf(f,"%s\n",lpKey->lpSubKey); - - if (lpKey->lpSubLvl) - _DumpLevel(f,lpKey,tabs+1); - lpKey=lpKey->lpNextKey; - } -} - -static void -_SaveKey(HKEY hKey,char *where) -{ - FILE *f; - LPKEYSTRUCT lpKey; - - f=fopen(where,"w"); - if (f==NULL) { - perror("registry-fopen"); - return; - } - switch ((DWORD)hKey) { - case HKEY_CLASSES_ROOT: - lpKey=lphRootKey; - break; - default:return; - } - _DumpLevel(f,lpKey,0); - fclose(f); -} - -void -SHELL_SaveRegistry(void) -{ - /* FIXME: - * -implement win95 additional keytypes here - * (HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER or whatever) - * -choose better filename(s) - */ - _SaveKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg"); -} - -#define BUFSIZE 256 -void -_LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf) -{ - int i; - char *s,*t; - HKEY hNewKey; - LPKEYSTRUCT lpNewKey; - - while (1) { - if (NULL==fgets(buf,BUFSIZE,f)) { - buf[0]=0; - return; - } - for (i=0;buf[i]=='\t';i++) /*empty*/; - s=buf+i; - if (NULL!=(t=strchr(s,'\n'))) *t='\0'; - if (NULL!=(t=strchr(s,'\r'))) *t='\0'; - - if (itabsexp) { - hNewKey=GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); - lpNewKey=lpKey->lpSubLvl=(LPKEYSTRUCT)GlobalLock(hNewKey); - lpNewKey->hKey = hNewKey; - lpNewKey->dwType = 0; - lpNewKey->lpSubKey = NULL; - lpNewKey->lpValue = NULL; - lpNewKey->lpSubLvl = NULL; - lpNewKey->lpNextKey = NULL; - lpNewKey->lpPrevKey = NULL; - if (NULL!=(t=strchr(s,'='))) { - *t='\0';t++; - lpNewKey->dwType = REG_SZ; - lpNewKey->lpSubKey = xstrdup(s); - lpNewKey->lpValue = xstrdup(t); - } else { - lpNewKey->dwType = REG_SZ; - lpNewKey->lpSubKey = xstrdup(s); - } - _LoadLevel(f,lpNewKey,tabsexp+1,buf); - } - for (i=0;buf[i]=='\t';i++) /*empty*/; - s=buf+i; - if (ilpNextKey=(LPKEYSTRUCT)GlobalLock(hNewKey); - lpNewKey->lpPrevKey = lpKey; - lpNewKey->hKey = hNewKey; - lpNewKey->dwType = 0; - lpNewKey->lpSubKey = NULL; - lpNewKey->lpValue = NULL; - lpNewKey->lpSubLvl = NULL; - lpNewKey->lpNextKey = NULL; - if (NULL!=(t=strchr(s,'='))) { - *t='\0';t++; - lpNewKey->dwType = REG_SZ; - lpNewKey->lpSubKey = xstrdup(s); - lpNewKey->lpValue = xstrdup(t); - } else { - lpNewKey->dwType = REG_SZ; - lpNewKey->lpSubKey = xstrdup(s); - } - lpKey=lpNewKey; - } -} - -void -_LoadKey(HKEY hKey,char *from) -{ - FILE *f; - LPKEYSTRUCT lpKey; - char buf[BUFSIZE]; /* FIXME: long enough? */ - - f=fopen(from,"r"); - if (f==NULL) { - dprintf_reg(stddeb,"fopen-registry-read"); - return; - } - switch ((DWORD)hKey) { - case HKEY_CLASSES_ROOT: - lpKey=lphRootKey; - break; - default:return; - } - _LoadLevel(f,lpKey,-1,buf); -} - -void -SHELL_LoadRegistry(void) -{ - _LoadKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg"); -} - -/************************************************************************* - * RegOpenKey [SHELL.1] - */ -LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey) -{ - LPKEYSTRUCT lpKey,lpNextKey; - LPCSTR ptr; - char str[128]; - - dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n", - (DWORD)hKey, lpSubKey, lpSubKey, lphKey); - if (lphKey == NULL) return SHELL_ERROR_INVALID_PARAMETER; - switch((DWORD)hKey) { - case 0: - lpKey = lphTopKey; break; - case HKEY_CLASSES_ROOT: /* == 1 */ - case 0x80000000: - case 0x80000001: - lpKey = lphRootKey; break; - default: - dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", (DWORD)hKey); - lpKey = (LPKEYSTRUCT)GlobalLock(hKey); - } - if (lpSubKey == NULL || !*lpSubKey) { - *lphKey = hKey; - return SHELL_ERROR_SUCCESS; - } - while(*lpSubKey) { - ptr = strchr(lpSubKey,'\\'); - if (!ptr) ptr = lpSubKey + strlen(lpSubKey); - strncpy(str,lpSubKey,ptr-lpSubKey); - str[ptr-lpSubKey] = 0; - lpSubKey = ptr; - if (*lpSubKey) lpSubKey++; - - lpNextKey = lpKey->lpSubLvl; - while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { - lpKey = lpNextKey; - if (lpKey) lpNextKey = lpKey->lpNextKey; - } - if (lpKey == NULL) { - dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str); - return SHELL_ERROR_BADKEY; - } - } - *lphKey = lpKey->hKey; - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegCreateKey [SHELL.2] - */ -LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey) -{ - HKEY hNewKey; - LPKEYSTRUCT lpNewKey; - LPKEYSTRUCT lpKey; - LPKEYSTRUCT lpPrevKey; - LPCSTR ptr; - char str[128]; - - dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", (DWORD)hKey, lpSubKey, lphKey); - if (lphKey == NULL) return SHELL_ERROR_INVALID_PARAMETER; - switch((DWORD)hKey) { - case 0: - lpKey = lphTopKey; break; - case HKEY_CLASSES_ROOT: /* == 1 */ - case 0x80000000: - case 0x80000001: - lpKey = lphRootKey; break; - default: - dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", (DWORD)hKey); - lpKey = (LPKEYSTRUCT)GlobalLock(hKey); - } - if (lpSubKey == NULL || !*lpSubKey) { - *lphKey = hKey; - return SHELL_ERROR_SUCCESS; - } - while (*lpSubKey) { - dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey); - ptr = strchr(lpSubKey,'\\'); - if (!ptr) ptr = lpSubKey + strlen(lpSubKey); - strncpy(str,lpSubKey,ptr-lpSubKey); - str[ptr-lpSubKey] = 0; - lpSubKey = ptr; - if (*lpSubKey) lpSubKey++; - - lpPrevKey = lpKey; - lpKey = lpKey->lpSubLvl; - while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { - lpKey = lpKey->lpNextKey; - } - if (lpKey == NULL) { - hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT)); - lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lpNewKey == NULL) { - printf("RegCreateKey // Can't alloc new key !\n"); - return SHELL_ERROR_OUTOFMEMORY; - } - lpNewKey->hKey = hNewKey; - lpNewKey->lpSubKey = malloc(strlen(str) + 1); - if (lpNewKey->lpSubKey == NULL) { - printf("RegCreateKey // Can't alloc key string !\n"); - return SHELL_ERROR_OUTOFMEMORY; - } - strcpy(lpNewKey->lpSubKey, str); - lpNewKey->lpNextKey = lpPrevKey->lpSubLvl; - lpNewKey->lpPrevKey = NULL; - lpPrevKey->lpSubLvl = lpNewKey; - - lpNewKey->dwType = 0; - lpNewKey->lpValue = NULL; - lpNewKey->lpSubLvl = NULL; - *lphKey = hNewKey; - dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, (DWORD)hNewKey); - lpKey = lpNewKey; - } else { - *lphKey = lpKey->hKey; - dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, (DWORD)*lphKey); - } - } - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegCloseKey [SHELL.3] - */ -LONG RegCloseKey(HKEY hKey) -{ - dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%08lX);\n", (DWORD)hKey); - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegDeleteKey [SHELL.4] - */ -LONG RegDeleteKey(HKEY hKey, LPCSTR lpSubKey) -{ - dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%08lX, '%s');\n", - (DWORD)hKey, lpSubKey); - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegSetValue [SHELL.5] - */ -LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, - LPCSTR lpVal, DWORD dwIgnored) -{ - HKEY hRetKey; - LPKEYSTRUCT lpKey; - LONG dwRet; - dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n", - (DWORD)hKey, lpSubKey, dwType, lpVal, dwIgnored); - /*if (lpSubKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;*/ - if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER; - if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) { - dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n"); - if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) { - fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet); - return dwRet; - } - } - lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey); - if (lpKey == NULL) return SHELL_ERROR_BADKEY; - if (lpKey->lpValue != NULL) free(lpKey->lpValue); - lpKey->lpValue = xmalloc(strlen(lpVal) + 1); - strcpy(lpKey->lpValue, lpVal); - dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue); - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegQueryValue [SHELL.6] - */ -LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LPLONG lpcb) -{ - HKEY hRetKey; - LPKEYSTRUCT lpKey; - LONG dwRet; - int size; - dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n", - (DWORD)hKey, lpSubKey, lpVal, lpcb); - /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/ - if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER; - if (lpcb == NULL) return SHELL_ERROR_INVALID_PARAMETER; - if (!*lpcb) return SHELL_ERROR_INVALID_PARAMETER; - - if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) { - fprintf(stderr, "RegQueryValue // key not found !\n"); - return dwRet; - } - lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey); - if (lpKey == NULL) return SHELL_ERROR_BADKEY; - if (lpKey->lpValue != NULL) { - if ((size = strlen(lpKey->lpValue)+1) > *lpcb){ - strncpy(lpVal,lpKey->lpValue,*lpcb-1); - lpVal[*lpcb-1] = 0; - } else { - strcpy(lpVal,lpKey->lpValue); - *lpcb = size; - } - } else { - *lpVal = 0; - *lpcb = (LONG)1; - } - dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal); - return SHELL_ERROR_SUCCESS; -} - - -/************************************************************************* - * RegEnumKey [SHELL.7] - */ -LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize) -{ - LPKEYSTRUCT lpKey; - LONG len; - - dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", (DWORD)hKey, dwSubKey); - if (lpBuf == NULL) return SHELL_ERROR_INVALID_PARAMETER; - switch((DWORD)hKey) { - case 0: - lpKey = lphTopKey; break; - case HKEY_CLASSES_ROOT: /* == 1 */ - case 0x80000000: - case 0x80000001: - lpKey = lphRootKey; break; - default: - dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", (DWORD)hKey); - lpKey = (LPKEYSTRUCT)GlobalLock(hKey); - } - lpKey = lpKey->lpSubLvl; - while(lpKey != NULL){ - if (!dwSubKey){ - len = MIN(dwSize-1,strlen(lpKey->lpSubKey)); - strncpy(lpBuf,lpKey->lpSubKey,len); - lpBuf[len] = 0; - dprintf_reg(stddeb, "RegEnumKey: found %s\n",lpBuf); - return SHELL_ERROR_SUCCESS; - } - dwSubKey--; - lpKey = lpKey->lpNextKey; - } - dprintf_reg(stddeb, "RegEnumKey: key not found!\n"); - return SHELL_ERROR_INVALID_PARAMETER; -} - - /************************************************************************* * DragAcceptFiles [SHELL.9] */ @@ -681,8 +232,6 @@ INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon) { HANDLE handle; BOOL bRet; - DWORD WineProc,Win16Proc,Win32Proc; - static int initialized=0; if (szApp) strncpy(AppName, szApp, sizeof(AppName)); else *AppName = 0; @@ -693,22 +242,11 @@ INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon) AppMisc[sizeof(AppMisc)-1]=0; if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON)); - - if(!initialized) - { - WineProc=(DWORD)AboutDlgProc; - Win16Proc=(DWORD)GetWndProcEntry16("AboutDlgProc"); - Win32Proc=(DWORD)RELAY32_GetEntryPoint(RELAY32_GetBuiltinDLL("WINPROCS32"), - "AboutDlgProc",0); - ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc); - initialized=1; - } - handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ); if (!handle) return FALSE; bRet = DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd ), handle, hWnd, - GetWndProcEntry16("AboutDlgProc"), + MODULE_GetWndProcEntry16("AboutDlgProc"), (LONG)hIcon ); SYSRES_FreeResource( handle ); return bRet; diff --git a/misc/xmalloc.c b/misc/xmalloc.c index 0765edf084..a228f71a5b 100644 --- a/misc/xmalloc.c +++ b/misc/xmalloc.c @@ -35,7 +35,7 @@ void *xmalloc( int size ) void *xrealloc( void *ptr, int size ) { void *res = realloc (ptr, size); - if (res == NULL) + if ((res == NULL) && size) { fprintf (stderr, "Virtual memory exhausted.\n"); exit (1); diff --git a/miscemu/dosmem.c b/miscemu/dosmem.c index 92b0cdc176..d3d5fa9eb8 100644 --- a/miscemu/dosmem.c +++ b/miscemu/dosmem.c @@ -132,18 +132,13 @@ BOOL DOSMEM_Init(void) /*********************************************************************** - * DOSMEM_Alarm + * DOSMEM_Tick * - * Increment the BIOS tick counter. + * Increment the BIOS tick counter. Called by timer signal handler. */ -void DOSMEM_Alarm(void) +void DOSMEM_Tick(void) { - pBiosData->Ticks = INT1A_GetTicksSinceMidnight(); - printf( "Ticks = %ld\n", pBiosData->Ticks ); -/* - signal( SIGALRM, DOSMEM_Alarm ); - alarm( 1 ); -*/ + pBiosData->Ticks++; } @@ -154,6 +149,8 @@ void DOSMEM_Alarm(void) */ void DOSMEM_FillBiosSegment(void) { + extern void SIGNAL_StartBIOSTimer(void); + pBiosData = (BIOSDATA *)GlobalLock( DOSMEM_BiosSeg ); /* Clear all unused values */ @@ -179,8 +176,6 @@ void DOSMEM_FillBiosSegment(void) pBiosData->KbdBufferStart = 0x1e; pBiosData->KbdBufferEnd = 0x3e; -/* - signal( SIGALRM, DOSMEM_Alarm ); - alarm( 1 ); -*/ + SIGNAL_StartBIOSTimer(); } + diff --git a/miscemu/instr.c b/miscemu/instr.c index 1e54951d79..14ac461321 100644 --- a/miscemu/instr.c +++ b/miscemu/instr.c @@ -30,7 +30,6 @@ static WORD INSTR_ReplaceSelector( struct sigcontext_struct *context, WORD sel) { fprintf( stderr, "Direct access to segment 0x40 (cs:ip=%04x:%04lx).\n", CS_reg(context), EIP_reg(context) ); - DOSMEM_Alarm(); /* Increment BIOS clock */ return DOSMEM_BiosSeg; } return 0; /* Can't replace selector */ diff --git a/multimedia/time.c b/multimedia/time.c index c9e7f22050..f0e21fe3e9 100644 --- a/multimedia/time.c +++ b/multimedia/time.c @@ -13,11 +13,9 @@ #include "win.h" #include "ldt.h" #include "callback.h" -#include "module.h" #include "user.h" #include "driver.h" #include "mmsystem.h" -#include "selectors.h" #include "stddebug.h" #include "debug.h" @@ -103,7 +101,7 @@ void StartMMTime() mmSysTimeSMPTE.u.smpte.frame = 0; mmSysTimeSMPTE.u.smpte.fps = 0; mmSysTimeSMPTE.u.smpte.dummy = 0; - SetTimer(0, 1, 33, GetWndProcEntry16("MMSysTimeCallback")); + SetTimer(0, 1, 33, MODULE_GetWndProcEntry16("MMSysTimeCallback")); } } diff --git a/objects/oembitmap.c b/objects/oembitmap.c index 63204cf997..36bbe20aa1 100644 --- a/objects/oembitmap.c +++ b/objects/oembitmap.c @@ -94,8 +94,13 @@ static const struct { obm_dnarrowd, TRUE }, /* OBM_DNARROWD */ { obm_uparrowd, TRUE }, /* OBM_UPARROWD */ { obm_restored, TRUE }, /* OBM_RESTORED */ +#ifdef WIN_95_LOOK + { obm_zoomd_95, TRUE }, /* OBM_ZOOMD */ + { obm_reduced_95, TRUE }, /* OBM_REDUCED */ +#else { obm_zoomd, TRUE }, /* OBM_ZOOMD */ { obm_reduced, TRUE }, /* OBM_REDUCED */ +#endif { obm_restore, TRUE }, /* OBM_RESTORE */ #ifdef WIN_95_LOOK { obm_zoom_95, TRUE }, /* OBM_ZOOM */ diff --git a/objects/text.c b/objects/text.c index 2929a01dd1..6ad5d4e670 100644 --- a/objects/text.c +++ b/objects/text.c @@ -522,10 +522,15 @@ LONG TEXT_TabbedTextOut( HDC hdc, int x, int y, LPSTR lpstr, int count, BOOL fDisplayText) { WORD defWidth; - DWORD extent; - int i, tabPos = 0; + DWORD extent = 0; + int i, tabPos = x; + int start = x; - if (cTabStops == 1) defWidth = *lpTabPos; + if (cTabStops == 1) + { + defWidth = *lpTabPos; + cTabStops = 0; + } else { TEXTMETRIC tm; @@ -538,17 +543,17 @@ LONG TEXT_TabbedTextOut( HDC hdc, int x, int y, LPSTR lpstr, int count, for (i = 0; i < count; i++) if (lpstr[i] == '\t') break; extent = GetTextExtent( hdc, lpstr, i ); - while ((cTabStops > 0) && (nTabOrg + *lpTabPos < x + LOWORD(extent))) + while ((cTabStops > 0) && (nTabOrg + *lpTabPos <= x + LOWORD(extent))) { lpTabPos++; cTabStops--; } - if (lpstr[i] != '\t') + if (i == count) tabPos = x + LOWORD(extent); else if (cTabStops > 0) tabPos = nTabOrg + *lpTabPos; else - tabPos = (x + LOWORD(extent) + defWidth - 1) / defWidth * defWidth; + tabPos = nTabOrg + ((x + LOWORD(extent) - nTabOrg) / defWidth + 1) * defWidth; if (fDisplayText) { RECT r; @@ -561,7 +566,7 @@ LONG TEXT_TabbedTextOut( HDC hdc, int x, int y, LPSTR lpstr, int count, count -= i+1; lpstr += i+1; } - return tabPos; + return MAKELONG(tabPos - start, HIWORD(extent)); } diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog index c5a2349778..7688fe9fc8 100644 --- a/programs/progman/ChangeLog +++ b/programs/progman/ChangeLog @@ -1,3 +1,16 @@ +Sun Mar 24 12:28:22 1996 Ulrich Schmid + + * [Strings_En.c] [Strings_De.c] (deleted) + Use resources for stringtables. + + * [Xx.rc] + Added `WS_TABSTOP' + +Wed Mar 20 13:14:58 1996 Ulrich Schmid + + * [winexec.c] (deleted) + Moved code to loader/modules.c + Fri Mar 15 20:56:31 1996 Ulrich Schmid * [main.c] diff --git a/programs/progman/De.rc b/programs/progman/De.rc index 9284517a3a..5420f90a0d 100644 --- a/programs/progman/De.rc +++ b/programs/progman/De.rc @@ -4,9 +4,11 @@ * Copyright 1996 Ulrich Schmid */ -/* Menu */ +#define LANGUAGE_ID De +#define LANGUAGE_NUMBER 2 +#define LANGUAGE_MENU_ITEM "&Deutsch" -#define MENU_Xx MENU_De +/* Menu */ #define MENU_FILE "&Datei" #define MENU_FILE_NEW "&Neu..." @@ -48,30 +50,25 @@ #define DIALOG_BROWSE "&Durchsuchen..." #define DIALOG_HELP "&Hilfe" -#define DIALOG_NEW_Xx DIALOG_NEW_De #define DIALOG_NEW_CAPTION "Neues Programmobject" #define DIALOG_NEW_NEW "Neu" #define DIALOG_NEW_GROUP "Programmgrupp&e" #define DIALOG_NEW_PROGRAM "&Programm" -#define DIALOG_MOVE_Xx DIALOG_MOVE_De #define DIALOG_MOVE_CAPTION "Programm verschieben" #define DIALOG_MOVE_PROGRAM "Verschiebe Programm:" #define DIALOG_MOVE_FROM_GROUP "Von Programmgruppe:" #define DIALOG_MOVE_TO_GROUP "&In Gruppe:" -#define DIALOG_COPY_Xx DIALOG_COPY_De #define DIALOG_COPY_CAPTION "Programm kopieren" #define DIALOG_COPY_PROGRAM "Kopiere Programm:" #define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP #define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP -#define DIALOG_GROUP_Xx DIALOG_GROUP_De #define DIALOG_GROUP_CAPTION "Programmgruppeneigenschaften" #define DIALOG_GROUP_DESCRIPTION "&Beschreibung:" #define DIALOG_GROUP_FILE "&Gruppendatei:" -#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_De #define DIALOG_PROGRAM_CAPTION "Programmeigenschaften" #define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION #define DIALOG_PROGRAM_COMMAND_LINE "Befehls&zeile:" @@ -80,14 +77,45 @@ #define DIALOG_PROGRAM_SYMBOL "Als Sy&mbol" #define DIALOG_PROGRAM_OTHER_SYMBOL "Anderes &Symbol..." -#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_De #define DIALOG_SYMBOL_CAPTION "Symbol auswählen" #define DIALOG_SYMBOL_FILE "Datei&name:" #define DIALOG_SYMBOL_CURRENT "&Aktuelles Symbol:" -#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_De #define DIALOG_EXECUTE_CAPTION "Programm Ausführen" #define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE #define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL +/* Strings */ + +#define STRING_PROGRAM_MANAGER "Programm-Manager" +#define STRING_ERROR "FEHLER" +#define STRING_WARNING "ACHTUNG" +#define STRING_INFO "Information" +#define STRING_DELETE "Löschen" +#define STRING_DELETE_GROUP_s "Lösche Programmgruppe `%s' ?" +#define STRING_DELETE_PROGRAM_s "Lösche Programm `%s' ?" +#define STRING_NOT_IMPLEMENTED "Nicht implementiert" +#define STRING_FILE_READ_ERROR_s "Fehler beim Lesen von `%s'" +#define STRING_FILE_WRITE_ERROR_s "Fehler beim Schreiben von `%s'" + +#define STRING_GRPFILE_READ_ERROR_s "\ +Die Programmgruppendatei `%s' kann nicht geöffnet werden.\n\ +Soll weiterhin versucht werden, diese Datei zu laden?" + +#define STRING_OUT_OF_MEMORY "Zu wenig Hauptspeicher" +#define STRING_WINHELP_ERROR "Keine Hilfe verfügbar" +#define STRING_UNKNOWN_FEATURE_s "Unbekannte Eigenschaft in %s" +#define STRING_FILE_NOT_OVERWRITTEN_s "Datei `%s' existiert. Sie wird nicht überschrieben." +#define STRING_SAVE_GROUP_AS_s "\ +Die Programmgruppe wird als `%s' gesichert um \ +das Überschreiben der Originaldatei zu verhindern." + +#define STRING_NO_HOT_KEY "Keine" + +#define STRING_ALL_FILES "Alle Dateien (*.*)" +#define STRING_PROGRAMS "Programme" +#define STRING_LIBRARIES_DLL "Bibliotheken (*.dll)" +#define STRING_SYMBOL_FILES "Symboldataeien" +#define STRING_SYMBOLS_ICO "Symbole (*.ico)" + #include "Xx.rc" diff --git a/programs/progman/En.rc b/programs/progman/En.rc index 97fb14bcc7..c8fe792de5 100644 --- a/programs/progman/En.rc +++ b/programs/progman/En.rc @@ -4,9 +4,11 @@ * Copyright 1996 Ulrich Schmid */ -/* Menu */ +#define LANGUAGE_ID En +#define LANGUAGE_NUMBER 0 +#define LANGUAGE_MENU_ITEM "&English" -#define MENU_Xx MENU_En +/* Menu */ #define MENU_FILE "&File" #define MENU_FILE_NEW "&New..." @@ -48,30 +50,25 @@ #define DIALOG_BROWSE "&Browse" #define DIALOG_HELP "&Help" -#define DIALOG_NEW_Xx DIALOG_NEW_En #define DIALOG_NEW_CAPTION "New Program Object" #define DIALOG_NEW_NEW "New" #define DIALOG_NEW_GROUP "Program &group" #define DIALOG_NEW_PROGRAM "&Program" -#define DIALOG_MOVE_Xx DIALOG_MOVE_En #define DIALOG_MOVE_CAPTION "Move Program" #define DIALOG_MOVE_PROGRAM "Move program:" #define DIALOG_MOVE_FROM_GROUP "From group:" #define DIALOG_MOVE_TO_GROUP "&To group:" -#define DIALOG_COPY_Xx DIALOG_COPY_En #define DIALOG_COPY_CAPTION "Copy Program" #define DIALOG_COPY_PROGRAM "Copy program:" #define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP #define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP -#define DIALOG_GROUP_Xx DIALOG_GROUP_En #define DIALOG_GROUP_CAPTION "Program Group Attributes" #define DIALOG_GROUP_DESCRIPTION "&Description:" #define DIALOG_GROUP_FILE "&Group file:" -#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_En #define DIALOG_PROGRAM_CAPTION "Program Attributes" #define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION #define DIALOG_PROGRAM_COMMAND_LINE "&Command line:" @@ -80,14 +77,43 @@ #define DIALOG_PROGRAM_SYMBOL "As &Symbol" #define DIALOG_PROGRAM_OTHER_SYMBOL "&Other Symbol..." -#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_En #define DIALOG_SYMBOL_CAPTION "Select Symbol" #define DIALOG_SYMBOL_FILE "&Filename:" #define DIALOG_SYMBOL_CURRENT "&Current Symbol:" -#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_En #define DIALOG_EXECUTE_CAPTION "Execute Program" #define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE #define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL +/* Strings */ + +#define STRING_PROGRAM_MANAGER "Program Manager" +#define STRING_ERROR "ERROR" +#define STRING_WARNING "WARNING" +#define STRING_INFO "Information" +#define STRING_DELETE "Delete" +#define STRING_DELETE_GROUP_s "Delete group `%s' ?" +#define STRING_DELETE_PROGRAM_s "Delete program `%s' ?" +#define STRING_NOT_IMPLEMENTED "Not implemented" +#define STRING_FILE_READ_ERROR_s "Error reading `%s'" +#define STRING_FILE_WRITE_ERROR_s "Error writeing `%s'" + +#define STRING_GRPFILE_READ_ERROR_s "\ +The group file `%s' cannot be opened.\n\ +Should it be tried further on?" + +#define STRING_OUT_OF_MEMORY "Out of memory" +#define STRING_WINHELP_ERROR "Help not available" +#define STRING_UNKNOWN_FEATURE_s "Unknown feature in %s" +#define STRING_FILE_NOT_OVERWRITTEN_s "File `%s' exists. Not overwritten." +#define STRING_SAVE_GROUP_AS_s "Save group as `%s' to prevent overwriting original files" + +#define STRING_NO_HOT_KEY "None" + +#define STRING_ALL_FILES "All files (*.*)" +#define STRING_PROGRAMS "Programs" +#define STRING_LIBRARIES_DLL "Libraries (*.dll)" +#define STRING_SYMBOL_FILES "Symbol files" +#define STRING_SYMBOLS_ICO "Symbols (*.ico)" + #include "Xx.rc" diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in index 241c566b40..ee8a900bb7 100644 --- a/programs/progman/Makefile.in +++ b/programs/progman/Makefile.in @@ -18,8 +18,7 @@ STRINGOBJS = \ accel.o \ string.o \ $(LANGUAGES:%=%.o) \ - $(LICENSELANG:%=License_%.o) \ - $(LANGUAGES:%=Strings_%.o) + $(LICENSELANG:%=License_%.o) C_SRCS = $(MOSTOBJS:.o=.c) $(STRINGOBJS:.o=.c) diff --git a/programs/progman/README b/programs/progman/README index b145c280a3..8cd4c34bc6 100644 --- a/programs/progman/README +++ b/programs/progman/README @@ -12,5 +12,3 @@ It's possible to use an alternate `progman.ini' file by adding to `wine.conf' something like: [progman] progman.ini=/my/wine/path/progman.ini - -It's possible to start both Windows and UNIX programs. diff --git a/programs/progman/Strings_De.c b/programs/progman/Strings_De.c deleted file mode 100644 index de3d369db0..0000000000 --- a/programs/progman/Strings_De.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "progman.h" - -LPCSTR StringTableDe[NUMBER_OF_STRINGS] = -{ - "Programm-Manager", - "FEHLER", - "Information", - "Löschen", - "Lösche Programmgruppe `%s' ?", - "Lösche Programm `%s' ?", - "Nicht implementiert", - "Fehler beim Lesen von `%s'", - "Fehler beim Schreiben von `%s'", - - "Die Programmgruppendatei `%s' kann nicht geöffnet werden.\n" - "Soll weiterhin versucht werden, diese Datei zu laden?", - - "Zu wenig Hauptspeicher", - "Keine Hilfe verfügbar", - "Unbekannte Eigenschaft der `.grp' Datei", - "Datei `%s' existiert. Sie wird nicht überschrieben.", - "Die Programmgruppe wird als `%s' gesichert um das Überschreiben der Originaldatei zu verhindern.", - "Keine", - - "Alle Dateien (*.*)\0" "*.*\0" - "Programme\0" "*.exe;*.pif;*.com;*.bat\0", - - "Alle Dateien (*.*)\0" "*.*\0" - "Bibliotheken (*.dll)\0" "*.dll\0" - "Programme\0" "*.exe\0" - "Symboldateien\0" "*.ico;*.exe;*.dll\0" - "Symbole (*.ico)\0" "*.ico\0" -}; diff --git a/programs/progman/Strings_En.c b/programs/progman/Strings_En.c deleted file mode 100644 index da3f19df80..0000000000 --- a/programs/progman/Strings_En.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "progman.h" - -LPCSTR StringTableEn[NUMBER_OF_STRINGS] = -{ - "Program Manager", - "ERROR", - "Information", - "Delete", - "Delete group `%s' ?", - "Delete program `%s' ?", - "Not implemented", - "Error reading `%s'", - "Error writeing `%s'", - - "The group file `%s' cannot be opened.\n" - "Should it be tried further on?", - - "Out of memory", - "Help not available", - "Unknown feature in `.grp' file", - "File `%s' exists. Not overwritten.", - "Save group as `%s' to prevent overwriting original files", - "None", - - "All files (*.*)\0" "*.*\0" - "Programs\0" "*.exe;*.pif;*.com;*.bat\0", - - "All files (*.*)\0" "*.*\0" - "Libraries (*.dll)\0" "*.dll\0" - "Programs\0" "*.exe\0" - "Symbol files\0" "*.ico;*.exe;*.dll\0" - "Symbols (*.ico)\0" "*.ico\0" -}; diff --git a/programs/progman/Xx.rc b/programs/progman/Xx.rc index 44d7991d40..e08b09e4c0 100644 --- a/programs/progman/Xx.rc +++ b/programs/progman/Xx.rc @@ -6,9 +6,12 @@ #include "progman.h" +#define CONCAT(a, b) CONCAT1(a, b) +#define CONCAT1(a, b) a##b + /* Menu */ -MENU_Xx MENU +CONCAT(MENU_, LANGUAGE_ID) MENU { POPUP MENU_FILE { MENUITEM MENU_FILE_NEW, PM_NEW @@ -33,8 +36,8 @@ MENU_Xx MENU MENUITEM MENU_WINDOWS_ARRANGE, PM_ARRANGE } POPUP MENU_LANGUAGE { - MENUITEM "&English", PM_En - MENUITEM "&Deutsch", PM_De + /* Dummy item, will be removed */ + MENUITEM SEPARATOR } POPUP MENU_HELP { MENUITEM MENU_HELP_CONTENTS, PM_CONTENTS @@ -54,7 +57,7 @@ MENU_Xx MENU /* Dialog `New' */ -DIALOG_NEW_Xx DIALOG 0, 0, 170, 65 +CONCAT(DIALOG_NEW_, LANGUAGE_ID) DIALOG 0, 0, 170, 65 STYLE DS_MODALFRAME CAPTION DIALOG_NEW_CAPTION { @@ -62,14 +65,14 @@ RADIOBUTTON "", PM_NEW_GROUP, 10, 15, 10, 15 LTEXT DIALOG_NEW_GROUP, PM_NEW_GROUP, 20, 18, 80, 15 RADIOBUTTON "", PM_NEW_PROGRAM, 10, 35, 10, 15 LTEXT DIALOG_NEW_PROGRAM, PM_NEW_PROGRAM, 20, 38, 80, 15 -DEFPUSHBUTTON DIALOG_OK, IDOK, 105, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 105, 25, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 105, 45, 60, 15 +DEFPUSHBUTTON DIALOG_OK, IDOK, 105, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 105, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 105, 45, 60, 15, WS_TABSTOP } /* Dialog `Move' */ -DIALOG_MOVE_Xx DIALOG 0, 0, 250, 65 +CONCAT(DIALOG_MOVE_, LANGUAGE_ID) DIALOG 0, 0, 250, 65 STYLE DS_MODALFRAME CAPTION DIALOG_MOVE_CAPTION { @@ -78,15 +81,15 @@ LTEXT "", PM_PROGRAM, 95, 5, 90, 15 LTEXT DIALOG_MOVE_FROM_GROUP, IDIGNORE, 5, 13, 90, 15 LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15 LTEXT DIALOG_MOVE_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15 -COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST -DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15 +COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, WS_TABSTOP | CBS_DROPDOWNLIST +DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15, WS_TABSTOP } /* Dialog `Copy' */ -DIALOG_COPY_Xx DIALOG 0, 0, 250, 65 +CONCAT(DIALOG_COPY_, LANGUAGE_ID) DIALOG 0, 0, 250, 65 STYLE DS_MODALFRAME CAPTION DIALOG_COPY_CAPTION { @@ -95,80 +98,120 @@ LTEXT "", PM_PROGRAM, 95, 5, 90, 15 LTEXT DIALOG_COPY_FROM_GROUP, IDIGNORE, 5, 13, 90, 15 LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15 LTEXT DIALOG_COPY_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15 -COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST -DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15 +COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, WS_TABSTOP | CBS_DROPDOWNLIST +DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15, WS_TABSTOP } /* Dialog `Group attributes' */ -DIALOG_GROUP_Xx DIALOG 0, 0, 230, 65 +CONCAT(DIALOG_GROUP_, LANGUAGE_ID) DIALOG 0, 0, 230, 65 STYLE DS_MODALFRAME CAPTION DIALOG_GROUP_CAPTION { LTEXT DIALOG_GROUP_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 18, 50, 10 -EDITTEXT PM_DESCRIPTION, 60, 18, 90, 15 +EDITTEXT PM_DESCRIPTION, 60, 18, 90, 15, WS_TABSTOP LTEXT DIALOG_GROUP_FILE, PM_FILE_TXT, 05, 38, 50, 10 -EDITTEXT PM_FILE, 60, 38, 90, 15 -DEFPUSHBUTTON DIALOG_OK, IDOK, 155, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 155, 25, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 155, 45, 60, 15 +EDITTEXT PM_FILE, 60, 38, 90, 15, WS_TABSTOP +DEFPUSHBUTTON DIALOG_OK, IDOK, 155, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 155, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 155, 45, 60, 15, WS_TABSTOP } /* Dialog `Program attributes' */ -DIALOG_PROGRAM_Xx DIALOG 0, 0, 250, 105 +CONCAT(DIALOG_PROGRAM_, LANGUAGE_ID) DIALOG 0, 0, 250, 105 STYLE DS_MODALFRAME CAPTION DIALOG_PROGRAM_CAPTION { LTEXT DIALOG_PROGRAM_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 10, 60, 10 -EDITTEXT PM_DESCRIPTION, 80, 10, 90, 15 +EDITTEXT PM_DESCRIPTION, 80, 10, 90, 15, WS_TABSTOP LTEXT DIALOG_PROGRAM_COMMAND_LINE, PM_COMMAND_LINE_TXT, 05, 25, 60, 10 -EDITTEXT PM_COMMAND_LINE, 80, 25, 90, 15 +EDITTEXT PM_COMMAND_LINE, 80, 25, 90, 15, WS_TABSTOP LTEXT DIALOG_PROGRAM_DIRECTORY, PM_DIRECTORY_TXT, 05, 40, 60, 10 -EDITTEXT PM_DIRECTORY, 80, 40, 90, 15 +EDITTEXT PM_DIRECTORY, 80, 40, 90, 15, WS_TABSTOP LTEXT DIALOG_PROGRAM_HOT_KEY, PM_HOT_KEY_TXT, 05, 55, 60, 10 -EDITTEXT PM_HOT_KEY, 80, 55, 90, 15 +EDITTEXT PM_HOT_KEY, 80, 55, 90, 15, WS_TABSTOP ICON "", PM_ICON, 20, 70 -CHECKBOX "", PM_SYMBOL, 80, 75, 10, 10 +CHECKBOX "", PM_SYMBOL, 80, 75, 10, 10, WS_TABSTOP LTEXT DIALOG_PROGRAM_SYMBOL, IDIGNORE, 95, 75, 75, 10 -DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15 -PUSHBUTTON DIALOG_BROWSE, PM_BROWSE, 185, 45, 60, 15 -PUSHBUTTON DIALOG_PROGRAM_OTHER_SYMBOL, PM_OTHER_SYMBOL, 185, 65, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 85, 60, 15 +DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_BROWSE, PM_BROWSE, 185, 45, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_PROGRAM_OTHER_SYMBOL, PM_OTHER_SYMBOL, 185, 65, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 85, 60, 15, WS_TABSTOP } /* Dialog `Symbol' */ -DIALOG_SYMBOL_Xx DIALOG 0, 0, 200, 85 +CONCAT(DIALOG_SYMBOL_, LANGUAGE_ID) DIALOG 0, 0, 200, 85 STYLE DS_MODALFRAME CAPTION DIALOG_SYMBOL_CAPTION { LTEXT DIALOG_SYMBOL_FILE, PM_ICON_FILE_TXT, 5, 15, 40, 10 -EDITTEXT PM_ICON_FILE, 45, 15, 85, 15 +EDITTEXT PM_ICON_FILE, 45, 15, 85, 15, WS_TABSTOP LTEXT DIALOG_SYMBOL_CURRENT, PM_SYMBOL_LIST_TXT, 5, 30, 125, 10 COMBOBOX PM_SYMBOL_LIST, 5, 40, 125, 50, - CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OWNERDRAWFIXED -DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15 -PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15 + CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OWNERDRAWFIXED | WS_TABSTOP +DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15, WS_TABSTOP } /* Dialog `Execute' */ -DIALOG_EXECUTE_Xx DIALOG 0, 0, 200, 85 +CONCAT(DIALOG_EXECUTE_, LANGUAGE_ID) DIALOG 0, 0, 200, 85 STYLE DS_MODALFRAME CAPTION DIALOG_EXECUTE_CAPTION { LTEXT DIALOG_EXECUTE_COMMAND_LINE, IDIGNORE, 05, 15, 120, 10 -EDITTEXT PM_COMMAND, 05, 25, 120, 15 -CHECKBOX "", PM_SYMBOL, 05, 45, 10, 10 +EDITTEXT PM_COMMAND, 05, 25, 120, 15, WS_TABSTOP +CHECKBOX "", PM_SYMBOL, 05, 45, 10, 10, WS_TABSTOP LTEXT DIALOG_EXECUTE_SYMBOL, IDIGNORE, 20, 45, 120, 10 -DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15 -PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15 -PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15 -PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15 +DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15, WS_TABSTOP +PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15, WS_TABSTOP +} + +/* Strings */ + +#define ADDSTRING(str) ADDSTRING1(LANGUAGE_NUMBER, IDS_ ## str) STRING_ ## str +#define ADDSTRING1(langnum, ids) ADDSTRING2(langnum, ids) +#define ADDSTRING2(langnum, ids) 0x ## langnum ## ids + +#define STRINGIFY(str) STRINGIFY1(str) +#define STRINGIFY1(str) #str + +#define STRING_LANGUAGE_ID STRINGIFY(LANGUAGE_ID) +#define STRING_LANGUAGE_MENU_ITEM LANGUAGE_MENU_ITEM + +STRINGTABLE +{ +ADDSTRING(LANGUAGE_ID) +ADDSTRING(LANGUAGE_MENU_ITEM) +ADDSTRING(PROGRAM_MANAGER) +ADDSTRING(ERROR) +ADDSTRING(WARNING) +ADDSTRING(INFO) +ADDSTRING(DELETE) +ADDSTRING(DELETE_GROUP_s) +ADDSTRING(DELETE_PROGRAM_s) +ADDSTRING(NOT_IMPLEMENTED) +ADDSTRING(FILE_READ_ERROR_s) +ADDSTRING(FILE_WRITE_ERROR_s) +ADDSTRING(GRPFILE_READ_ERROR_s) +ADDSTRING(OUT_OF_MEMORY) +ADDSTRING(WINHELP_ERROR) +ADDSTRING(UNKNOWN_FEATURE_s) +ADDSTRING(FILE_NOT_OVERWRITTEN_s) +ADDSTRING(SAVE_GROUP_AS_s) +ADDSTRING(NO_HOT_KEY) +ADDSTRING(ALL_FILES) +ADDSTRING(PROGRAMS) +ADDSTRING(LIBRARIES_DLL) +ADDSTRING(SYMBOL_FILES) +ADDSTRING(SYMBOLS_ICO) } diff --git a/programs/progman/dialog.c b/programs/progman/dialog.c index c19ca83809..f35d4256f8 100644 --- a/programs/progman/dialog.c +++ b/programs/progman/dialog.c @@ -8,7 +8,8 @@ #include #include "progman.h" -static BOOL DIALOG_Browse(HWND, LPCSTR, LPSTR, INT); +static BOOL DIALOG_BrowsePrograms(HWND, LPSTR, INT); +static BOOL DIALOG_BrowseSymbols(HWND, LPSTR, INT); static LRESULT DIALOG_NEW_DlgProc(HWND, UINT, WPARAM, LPARAM); static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND, UINT, WPARAM, LPARAM); static LRESULT DIALOG_GROUP_DlgProc(HWND, UINT, WPARAM, LPARAM); @@ -157,13 +158,10 @@ static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPAR * DIALOG_Delete */ -BOOL DIALOG_Delete(LPCSTR lpszFormat_s, LPCSTR lpszName) +BOOL DIALOG_Delete(UINT ids_text_s, LPCSTR lpszName) { - CHAR msg[1000]; - if (sizeof(msg) <= lstrlen(lpszFormat_s) + lstrlen(lpszName)) return FALSE; - wsprintf(msg, (LPSTR)lpszFormat_s, lpszName); - return (IDYES == MessageBox(Globals.hMainWnd, msg, STRING_DELETE, - MB_YESNO | MB_DEFBUTTON2)); + return (IDYES == MAIN_MessageBoxIDS_s(ids_text_s, lpszName, IDS_DELETE, + MB_YESNO | MB_DEFBUTTON2)); } @@ -284,6 +282,7 @@ BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine, static LRESULT DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + CHAR buffer[MAX_STRING_LEN]; switch (msg) { case WM_INITDIALOG: @@ -291,7 +290,10 @@ static LRESULT DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM SetDlgItemText(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine); SetDlgItemText(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir); if (!*ProgramAttributes.lpnHotKey) - SetDlgItemText(hDlg, PM_HOT_KEY, (LPSTR)STRING_NO_HOT_KEY); + { + LoadString(Globals.hInstance, IDS_NO_HOT_KEY, buffer, sizeof(buffer)); + SetDlgItemText(hDlg, PM_HOT_KEY, buffer); + } CheckDlgButton(hDlg, PM_SYMBOL, (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED)); @@ -309,8 +311,7 @@ static LRESULT DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM case PM_BROWSE: { CHAR filename[MAX_PATHNAME_LEN]; - if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER, - filename, sizeof(filename))) + if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename))) SetDlgItemText(hDlg, PM_COMMAND_LINE, filename); return TRUE; } @@ -432,14 +433,13 @@ static LRESULT DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM case PM_BROWSE: { CHAR filename[MAX_PATHNAME_LEN]; - if (DIALOG_Browse(hDlg, STRING_BROWSE_ICO_FILTER, - filename, sizeof(filename))) + if (DIALOG_BrowseSymbols(hDlg, filename, sizeof(filename))) SetDlgItemText(hDlg, PM_ICON_FILE, filename); return TRUE; } case PM_HELP: - MAIN_NotImplementedError(); + MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK); return TRUE; case IDOK: @@ -500,14 +500,13 @@ static LRESULT DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg, case PM_BROWSE: { CHAR filename[MAX_PATHNAME_LEN]; - if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER, - filename, sizeof(filename))) + if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename))) SetDlgItemText(hDlg, PM_COMMAND, filename); return TRUE; } case PM_HELP: - MAIN_NotImplementedError(); + MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK); return TRUE; case IDOK: @@ -536,15 +535,16 @@ static LRESULT DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg, * DIALOG_Browse */ -/* FIXME is this correct ? */ -static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpcstrFilter, +static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpszzFilter, LPSTR lpstrFile, INT nMaxFile) { OPENFILENAME openfilename; + + /* FIXME is this correct ? */ openfilename.lStructSize = 0; openfilename.hwndOwner = hDlg; openfilename.hInstance = Globals.hInstance; - openfilename.lpstrFilter = (LPSTR)lpcstrFilter; + openfilename.lpstrFilter = (LPSTR)lpszzFilter; openfilename.lpstrCustomFilter = 0; openfilename.nMaxCustFilter = 0; openfilename.nFilterIndex = 0; @@ -564,6 +564,55 @@ static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpcstrFilter, return GetOpenFileName(&openfilename); } +/*********************************************************************** + * + * DIALOG_AddFilterItem + */ + +static VOID DIALOG_AddFilterItem(LPSTR *p, UINT ids, LPCSTR filter) +{ + LoadString(Globals.hInstance, ids, *p, MAX_STRING_LEN); + *p += strlen(*p) + 1; + lstrcpy(*p, (SEGPTR) filter); + *p += strlen(*p) + 1; + **p = '\0'; +} + +/*********************************************************************** + * + * DIALOG_BrowsePrograms + */ + +static BOOL DIALOG_BrowsePrograms(HWND hDlg, LPSTR lpszFile, INT nMaxFile) +{ + CHAR szzFilter[2 * MAX_STRING_LEN + 100]; + LPSTR p = szzFilter; + + DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe;*.pif;*.com;*.bat"); + DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*"); + + return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile)); +} + +/*********************************************************************** + * + * DIALOG_BrowseSymbols + */ + +static BOOL DIALOG_BrowseSymbols(HWND hDlg, LPSTR lpszFile, INT nMaxFile) +{ + CHAR szzFilter[5 * MAX_STRING_LEN + 100]; + LPSTR p = szzFilter; + + DIALOG_AddFilterItem(&p, IDS_SYMBOL_FILES, "*.ico;*.exe;*.dll"); + DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe"); + DIALOG_AddFilterItem(&p, IDS_LIBRARIES_DLL, "*.dll"); + DIALOG_AddFilterItem(&p, IDS_SYMBOLS_ICO, "*.ico"); + DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*"); + + return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile)); +} + /* Local Variables: */ /* c-file-style: "GNU" */ /* End: */ diff --git a/programs/progman/group.c b/programs/progman/group.c index 0646f8fc15..a133b55a4d 100644 --- a/programs/progman/group.c +++ b/programs/progman/group.c @@ -109,7 +109,7 @@ HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT nCmdShow, HLOCAL hGrpFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszGrpFile)); if (!hGroup || !hName || !hGrpFile) { - MessageBox(Globals.hMainWnd, "out of memory", lpszName, MB_OK); + MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK); if (hGroup) LocalFree(hGroup); if (hName) LocalFree(hName); if (hGrpFile) LocalFree(hGrpFile); diff --git a/programs/progman/grpfile.c b/programs/progman/grpfile.c index 50e99ecc32..1e292a0642 100644 --- a/programs/progman/grpfile.c +++ b/programs/progman/grpfile.c @@ -63,14 +63,15 @@ HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath) /* Read the whole file into a buffer */ if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size)) { - MAIN_GrpFileReadError(lpszPath); + MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO); return(0); } /* Interpret buffer */ hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size, lpszPath, bFileNameModified); - if (!hGroup) MAIN_GrpFileReadError(lpszPath); + if (!hGroup) + MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO); LocalFree(hBuffer); @@ -225,8 +226,8 @@ static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size, switch (icontype) { default: - MessageBox(Globals.hMainWnd, STRING_UNKNOWN_FEATURE_IN_GRPFILE, - lpszGrpFile, MB_OK); + MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile, + IDS_WARNING, MB_OK); case 0x048c: iconXORsize = GET_USHORT(program_ptr, 8); iconANDsize = GET_USHORT(program_ptr, 10) / 8; @@ -305,9 +306,8 @@ static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size, nCmdShow = GET_USHORT(ptr, 6); break; default: - MessageBox(Globals.hMainWnd, - STRING_UNKNOWN_FEATURE_IN_GRPFILE, - lpszGrpFile, MB_OK); + MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, + lpszGrpFile, IDS_WARNING, MB_OK); } } if (!skip) break; @@ -344,26 +344,20 @@ BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup) if (!group->bOverwriteFileOk && OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR) { - CHAR msg[MAX_PATHNAME_LEN + 1000]; - /* Original file exists, try `.gr' extension */ GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile), MAX_PATHNAME_LEN, TRUE); if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR) { /* File exists. Do not overwrite */ - if (sizeof(msg) <= lstrlen(STRING_FILE_NOT_OVERWRITTEN_s) + lstrlen(szPath)) - return FALSE; - wsprintf(msg, (LPSTR)STRING_FILE_NOT_OVERWRITTEN_s, szPath); - MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK); + MAIN_MessageBoxIDS_s(IDS_FILE_NOT_OVERWRITTEN_s, szPath, + IDS_INFO, MB_OK); return FALSE; } /* Inform about the modified file name */ - if (sizeof(msg) <= lstrlen(STRING_SAVE_GROUP_AS_s) + lstrlen(szPath)) - return FALSE; - wsprintf(msg, (LPSTR)STRING_SAVE_GROUP_AS_s, szPath); - if (IDCANCEL == MessageBox(Globals.hMainWnd, msg, STRING_INFO, - MB_OKCANCEL | MB_ICONINFORMATION)) + if (IDCANCEL == + MAIN_MessageBoxIDS_s(IDS_SAVE_GROUP_AS_s, szPath, IDS_INFO, + MB_OKCANCEL | MB_ICONINFORMATION)) return FALSE; } @@ -395,7 +389,8 @@ BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup) } else ret = FALSE; - if (!ret) MAIN_FileWriteError(szPath); + if (!ret) + MAIN_MessageBoxIDS_s(IDS_FILE_WRITE_ERROR_s, szPath, IDS_ERROR, MB_OK); return(ret); } diff --git a/programs/progman/main.c b/programs/progman/main.c index 4d3cd13af2..e9906ffce5 100644 --- a/programs/progman/main.c +++ b/programs/progman/main.c @@ -34,6 +34,13 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) { MSG msg; +#if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR) + /* Register resources */ + LIBWINE_Register_accel(); + LIBWINE_Register_De(); + LIBWINE_Register_En(); +#endif + #ifndef WINELIB Globals.lpszIniFile = "progman.ini"; Globals.lpszIcoFile = "progman.ico"; @@ -56,28 +63,15 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) #endif /* Select Language */ - Globals.lpszLanguage = "En"; #ifdef WINELIB - if (Options.language == LANG_Cz) Globals.lpszLanguage = "Cz"; - if (Options.language == LANG_Da) Globals.lpszLanguage = "Da"; - if (Options.language == LANG_De) Globals.lpszLanguage = "De"; - if (Options.language == LANG_Es) Globals.lpszLanguage = "Es"; - if (Options.language == LANG_Fi) Globals.lpszLanguage = "Fi"; - if (Options.language == LANG_Fr) Globals.lpszLanguage = "Fr"; - if (Options.language == LANG_No) Globals.lpszLanguage = "No"; -#ifndef HAVE_WINE_CONSTRUCTOR - /* Register resources */ - LIBWINE_Register_accel(); - LIBWINE_Register_De(); - LIBWINE_Register_En(); -#endif + Globals.lpszLanguage = langNames[Options.language]; +#else + Globals.lpszLanguage = "En"; #endif Globals.hInstance = hInstance; Globals.hGroups = 0; - - /* FIXME should use MDI */ - Globals.hActiveGroup = 0; + Globals.hActiveGroup = 0; /* Read Options from `progman.ini' */ Globals.bAutoArrange = @@ -108,7 +102,7 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL); /* Setup menu, stringtable and resourcenames */ - STRING_SelectLanguage(Globals.lpszLanguage); + STRING_SelectLanguageByName(Globals.lpszLanguage); MAIN_CreateMDIWindow(); @@ -146,7 +140,8 @@ static VOID MAIN_CreateGroups() { int num, skip, ret; ret = sscanf(ptr, "%d%n", &num, &skip); - if (ret == 0) MAIN_FileReadError(Globals.lpszIniFile); + if (ret == 0) + MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK); if (ret != 1) break; sprintf(key, "Group%d", num); @@ -259,12 +254,12 @@ static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case PM_DELETE: if (hActiveProgram) { - if (DIALOG_Delete(STRING_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram))) + if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram))) PROGRAM_DeleteProgram(hActiveProgram, TRUE); } else if (hActiveGroup) { - if (DIALOG_Delete(STRING_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup))) + if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup))) GROUP_DeleteGroup(hActiveGroup); } break; @@ -326,24 +321,15 @@ static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0); break; - /* Menu Language */ - case PM_Da: STRING_SelectLanguage("Da"); break; - case PM_De: STRING_SelectLanguage("De"); break; - case PM_En: STRING_SelectLanguage("En"); break; - case PM_Es: STRING_SelectLanguage("Es"); break; - case PM_Fi: STRING_SelectLanguage("Fi"); break; - case PM_Fr: STRING_SelectLanguage("Fr"); break; - case PM_No: STRING_SelectLanguage("No"); break; - /* Menu Help */ case PM_CONTENTS: if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_INDEX, 0)) - MAIN_WinHelpError(); + MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK); break; case PM_HELPONHELP: if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0)) - MAIN_WinHelpError(); + MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK); break; case PM_TUTORIAL: @@ -368,7 +354,10 @@ static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) #endif default: - MAIN_NotImplementedError(); + if (wParam >= PM_FIRST_LANGUAGE && wParam <= PM_LAST_LANGUAGE) + STRING_SelectLanguageByNumber(wParam - PM_FIRST_LANGUAGE); + else + MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK); break; } } @@ -462,6 +451,38 @@ static VOID MAIN_CreateMDIWindow() } /**********************************************************************/ +/*********************************************************************** + * + * MAIN_MessageBoxIDS + */ +INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type) +{ + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + + return(MessageBox(Globals.hMainWnd, text, title, type)); +} + +/*********************************************************************** + * + * MAIN_MessageBoxIDS_s + */ +INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type) +{ + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; + CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN]; + + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + wsprintf(newtext, text, str); + + return(MessageBox(Globals.hMainWnd, newtext, title, type)); +} + /*********************************************************************** * * MAIN_ReplaceString @@ -477,79 +498,7 @@ VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace) LocalFree(*handle); *handle = newhandle; } - else MAIN_OutOfMemoryError(); -} - -/*********************************************************************** - * - * MAIN_NotImplementedError - */ - -VOID MAIN_NotImplementedError() -{ - MessageBox(Globals.hMainWnd, - STRING_NOT_IMPLEMENTED, STRING_ERROR, MB_OK); -} - -/*********************************************************************** - * - * MAIN_OutOfMemoryError - */ - -VOID MAIN_OutOfMemoryError() -{ - MessageBox(Globals.hMainWnd, - STRING_OUT_OF_MEMORY, STRING_ERROR, MB_OK); -} - -/*********************************************************************** - * - * MAIN_WinHelpError - */ - -VOID MAIN_WinHelpError() -{ - MessageBox(Globals.hMainWnd, - STRING_WINHELP_ERROR, STRING_ERROR, MB_OK); -} - -/*********************************************************************** - * - * MAIN_FileReadError - */ - -VOID MAIN_FileReadError(LPCSTR lpszPath) -{ - CHAR msg[MAX_PATHNAME_LEN + 1000]; - if (sizeof(msg) <= strlen(STRING_FILE_READ_ERROR_s) + strlen(lpszPath)) return; - wsprintf(msg, (LPSTR)STRING_FILE_READ_ERROR_s, lpszPath); - MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK); -} - -/*********************************************************************** - * - * MAIN_FileWriteError - */ - -VOID MAIN_FileWriteError(LPCSTR lpszPath) -{ - CHAR msg[MAX_PATHNAME_LEN + 1000]; - if (sizeof(msg) <= strlen(STRING_FILE_WRITE_ERROR_s) + strlen(lpszPath)) return; - wsprintf(msg, (LPSTR)STRING_FILE_WRITE_ERROR_s, lpszPath); - MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK); -} - -/*********************************************************************** - * - * MAIN_GrpFileReadError - */ - -VOID MAIN_GrpFileReadError(LPCSTR lpszPath) -{ - CHAR msg[MAX_PATHNAME_LEN + 1000]; - if (sizeof(msg) <= strlen(STRING_GRPFILE_READ_ERROR_s) + strlen(lpszPath)) return; - wsprintf(msg, (LPSTR)STRING_GRPFILE_READ_ERROR_s, lpszPath); - MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_YESNO); + else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK); } /* Local Variables: */ diff --git a/programs/progman/progman.h b/programs/progman/progman.h index 875598bb12..c2dea1fe36 100644 --- a/programs/progman/progman.h +++ b/programs/progman/progman.h @@ -7,12 +7,14 @@ #ifndef PROGMAN_H #define PROGMAN_H +#define MAX_STRING_LEN 255 +#define MAX_PATHNAME_LEN 1024 +#define MAX_LANGUAGE_NUMBER (PM_LAST_LANGUAGE - PM_FIRST_LANGUAGE) + #ifndef RC_INVOKED #include "windows.h" -#define MAX_PATHNAME_LEN 1024 - /* Fallback icon */ #ifdef WINELIB #define DEFAULTICON OIC_WINEICON @@ -113,6 +115,7 @@ typedef struct HMENU hFileMenu; HMENU hOptionMenu; HMENU hWindowsMenu; + HMENU hLanguageMenu; LPCSTR lpszIniFile; LPCSTR lpszIcoFile; BOOL bAutoArrange; @@ -120,20 +123,15 @@ typedef struct BOOL bMinOnRun; HLOCAL hGroups; LPCSTR lpszLanguage; - LPCSTR *StringTable; - /* FIXME should use MDI */ + UINT wStringTableOffset; HLOCAL hActiveGroup; } GLOBALS; extern GLOBALS Globals; +INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type); +INT MAIN_MessageBoxIDS_s(UINT ids_text_s, LPCSTR str, UINT ids_title, WORD type); VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replacestring); -VOID MAIN_NotImplementedError(void); -VOID MAIN_FileReadError(LPCSTR lpszPath); -VOID MAIN_FileWriteError(LPCSTR lpszPath); -VOID MAIN_GrpFileReadError(LPCSTR lpszPath); -VOID MAIN_OutOfMemoryError(void); -VOID MAIN_WinHelpError(void); HLOCAL GRPFILE_ReadGroupFile(const char* path); BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup); @@ -173,7 +171,7 @@ VOID PROGRAM_ExecuteProgram(HLOCAL hLocal); INT DIALOG_New(INT nDefault); HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszGroupName, BOOL bMove); -BOOL DIALOG_Delete(LPCSTR lpszFormat, LPCSTR lpszName); +BOOL DIALOG_Delete(UINT ids_format_s, LPCSTR lpszName); BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszPath, INT nSize); BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine, LPSTR lpszWorkDir, LPSTR lpszIconFile, @@ -183,7 +181,8 @@ VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile, INT *lpnIconIndex, INT nSize); VOID DIALOG_Execute(void); -VOID STRING_SelectLanguage(LPCSTR lang); +VOID STRING_SelectLanguageByName(LPCSTR); +VOID STRING_SelectLanguageByNumber(UINT); /* Class names */ extern CHAR STRING_MAIN_WIN_CLASS_NAME[]; @@ -204,49 +203,39 @@ extern CHAR STRING_PROGRAM_Xx[]; extern CHAR STRING_SYMBOL_Xx[]; extern CHAR STRING_EXECUTE_Xx[]; -/* Strings */ -#define STRING_PROGRAM_MANAGER Globals.StringTable[ 0] -#define STRING_ERROR Globals.StringTable[ 1] -#define STRING_INFO Globals.StringTable[ 2] -#define STRING_DELETE Globals.StringTable[ 3] -#define STRING_DELETE_GROUP_s Globals.StringTable[ 4] -#define STRING_DELETE_PROGRAM_s Globals.StringTable[ 5] -#define STRING_NOT_IMPLEMENTED Globals.StringTable[ 6] -#define STRING_FILE_READ_ERROR_s Globals.StringTable[ 7] -#define STRING_FILE_WRITE_ERROR_s Globals.StringTable[ 8] -#define STRING_GRPFILE_READ_ERROR_s Globals.StringTable[ 9] -#define STRING_OUT_OF_MEMORY Globals.StringTable[10] -#define STRING_WINHELP_ERROR Globals.StringTable[11] -#define STRING_UNKNOWN_FEATURE_IN_GRPFILE Globals.StringTable[12] -#define STRING_FILE_NOT_OVERWRITTEN_s Globals.StringTable[13] -#define STRING_SAVE_GROUP_AS_s Globals.StringTable[14] -#define STRING_NO_HOT_KEY Globals.StringTable[15] -#define STRING_BROWSE_EXE_FILTER Globals.StringTable[16] -#define STRING_BROWSE_ICO_FILTER Globals.StringTable[17] -#define NUMBER_OF_STRINGS 18 +#define STRINGID(id) (0x##id + Globals.wStringTableOffset) -extern LPCSTR StringTableCz[]; -extern LPCSTR StringTableDa[]; -extern LPCSTR StringTableDe[]; -extern LPCSTR StringTableEn[]; -extern LPCSTR StringTableEs[]; -extern LPCSTR StringTableFi[]; -extern LPCSTR StringTableFr[]; -extern LPCSTR StringTableNo[]; +#else /* RC_INVOKED */ + +#define STRINGID(id) id -#if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR) - VOID LIBWINE_Register_accel(void); - VOID LIBWINE_Register_Cz(void); - VOID LIBWINE_Register_Da(void); - VOID LIBWINE_Register_De(void); - VOID LIBWINE_Register_Es(void); - VOID LIBWINE_Register_En(void); - VOID LIBWINE_Register_Fi(void); - VOID LIBWINE_Register_Fr(void); - VOID LIBWINE_Register_No(void); #endif -#endif /* !RC_INVOKED */ +/* Stringtable index */ +#define IDS_LANGUAGE_ID STRINGID(00) +#define IDS_LANGUAGE_MENU_ITEM STRINGID(01) +#define IDS_PROGRAM_MANAGER STRINGID(02) +#define IDS_ERROR STRINGID(03) +#define IDS_WARNING STRINGID(04) +#define IDS_INFO STRINGID(05) +#define IDS_DELETE STRINGID(06) +#define IDS_DELETE_GROUP_s STRINGID(07) +#define IDS_DELETE_PROGRAM_s STRINGID(08) +#define IDS_NOT_IMPLEMENTED STRINGID(09) +#define IDS_FILE_READ_ERROR_s STRINGID(0a) +#define IDS_FILE_WRITE_ERROR_s STRINGID(0b) +#define IDS_GRPFILE_READ_ERROR_s STRINGID(0c) +#define IDS_OUT_OF_MEMORY STRINGID(0d) +#define IDS_WINHELP_ERROR STRINGID(0e) +#define IDS_UNKNOWN_FEATURE_s STRINGID(0f) +#define IDS_FILE_NOT_OVERWRITTEN_s STRINGID(10) +#define IDS_SAVE_GROUP_AS_s STRINGID(11) +#define IDS_NO_HOT_KEY STRINGID(12) +#define IDS_ALL_FILES STRINGID(13) +#define IDS_PROGRAMS STRINGID(14) +#define IDS_LIBRARIES_DLL STRINGID(15) +#define IDS_SYMBOL_FILES STRINGID(16) +#define IDS_SYMBOLS_ICO STRINGID(17) /* Menu */ @@ -268,14 +257,8 @@ extern LPCSTR StringTableNo[]; #define PM_ARRANGE 302 #define PM_FIRST_CHILD 3030 -#define PM_En 400 -#define PM_Es 401 -#define PM_De 402 -#define PM_No 403 -#define PM_Fr 404 -#define PM_Fi 405 -#define PM_Da 406 -#define PM_Cz 407 +#define PM_FIRST_LANGUAGE 400 +#define PM_LAST_LANGUAGE 499 #define PM_CONTENTS 501 #define PM_SEARCH 502 diff --git a/programs/progman/program.c b/programs/progman/program.c index d9e4b4a90a..b2ecdfb946 100644 --- a/programs/progman/program.c +++ b/programs/progman/program.c @@ -159,7 +159,7 @@ HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName, HLOCAL hWorkDir = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszWorkDir)); if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir) { - MAIN_OutOfMemoryError(); + MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK); if (hProgram) LocalFree(hProgram); if (hName) LocalFree(hName); if (hCmdLine) LocalFree(hCmdLine); diff --git a/programs/progman/string.c b/programs/progman/string.c index be7ae150f2..f33941b40e 100644 --- a/programs/progman/string.c +++ b/programs/progman/string.c @@ -20,7 +20,7 @@ CHAR STRING_PROGRAM_WIN_CLASS_NAME[] = "PMProgram"; /* Resource names */ /* Xx will be overwritten with En, ... */ CHAR STRING_ACCEL[] = "ACCEL"; -CHAR STRING_MAIN_Xx[] = "MENU_Xx"; +CHAR STRING_MENU_Xx[] = "MENU_Xx"; CHAR STRING_NEW_Xx[] = "DIALOG_NEW_Xx"; CHAR STRING_OPEN_Xx[] = "DIALOG_OPEN_Xx"; CHAR STRING_MOVE_Xx[] = "DIALOG_MOVE_Xx"; @@ -31,22 +31,60 @@ CHAR STRING_PROGRAM_Xx[] = "DIALOG_PROGRAM_Xx"; CHAR STRING_SYMBOL_Xx[] = "DIALOG_SYMBOL_Xx"; CHAR STRING_EXECUTE_Xx[] = "DIALOG_EXECUTE_Xx"; -static LPCSTR StringTableEn[]; -static LPCSTR StringTableDe[]; - -VOID STRING_SelectLanguage(LPCSTR lang) +static BOOL STRING_LoadStringOtherLanguage(UINT num, UINT ids, LPSTR str, UINT len) { + ids -= Globals.wStringTableOffset; + ids += num * 0x100; + return(LoadString(Globals.hInstance, ids, str, len)); +}; + +VOID STRING_SelectLanguageByName(LPCSTR lang) +{ + INT i; + CHAR newlang[3]; + + for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++) + if (STRING_LoadStringOtherLanguage(i, IDS_LANGUAGE_ID, newlang, sizeof(newlang)) && + !lstrcmp(lang, newlang)) + { + STRING_SelectLanguageByNumber(i); + return; + } + + /* Fallback */ + for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++) + if (STRING_LoadStringOtherLanguage(i, IDS_LANGUAGE_ID, newlang, sizeof(newlang))) + { + STRING_SelectLanguageByNumber(i); + return; + } + + MessageBox(Globals.hMainWnd, "No language found", "FATAL ERROR", MB_OK); + PostQuitMessage(1); +} + +VOID STRING_SelectLanguageByNumber(UINT num) +{ + INT i; + CHAR lang[3]; + CHAR caption[MAX_STRING_LEN]; + CHAR item[MAX_STRING_LEN]; HMENU hMainMenu; HLOCAL hGroup; - /* Change string table */ - Globals.StringTable = StringTableEn; - if (!lstrcmp(lang, "De")) Globals.StringTable = StringTableDe; + /* Select string table */ + Globals.wStringTableOffset = num * 0x100; - SetWindowText(Globals.hMainWnd, STRING_PROGRAM_MANAGER); + /* Get Language id */ + LoadString(Globals.hInstance, IDS_LANGUAGE_ID, lang, sizeof(lang)); + Globals.lpszLanguage = lang; + + /* Set frame caption */ + LoadString(Globals.hInstance, IDS_PROGRAM_MANAGER, caption, sizeof(caption)); + SetWindowText(Globals.hMainWnd, caption); /* Change Resource names */ - lstrcpyn(STRING_MAIN_Xx + sizeof(STRING_MAIN_Xx) - 3, lang, 3); + lstrcpyn(STRING_MENU_Xx + sizeof(STRING_MENU_Xx) - 3, lang, 3); lstrcpyn(STRING_NEW_Xx + sizeof(STRING_NEW_Xx) - 3, lang, 3); lstrcpyn(STRING_OPEN_Xx + sizeof(STRING_OPEN_Xx) - 3, lang, 3); lstrcpyn(STRING_MOVE_Xx + sizeof(STRING_MOVE_Xx) - 3, lang, 3); @@ -58,37 +96,35 @@ VOID STRING_SelectLanguage(LPCSTR lang) lstrcpyn(STRING_EXECUTE_Xx + sizeof(STRING_EXECUTE_Xx) - 3, lang, 3); /* Create menu */ - hMainMenu = LoadMenu(Globals.hInstance, STRING_MAIN_Xx); - if (hMainMenu) - { - Globals.hFileMenu = GetSubMenu(hMainMenu, 0); - Globals.hOptionMenu = GetSubMenu(hMainMenu, 1); - Globals.hWindowsMenu = GetSubMenu(hMainMenu, 2); + hMainMenu = LoadMenu(Globals.hInstance, STRING_MENU_Xx); + Globals.hFileMenu = GetSubMenu(hMainMenu, 0); + Globals.hOptionMenu = GetSubMenu(hMainMenu, 1); + Globals.hWindowsMenu = GetSubMenu(hMainMenu, 2); + Globals.hLanguageMenu = GetSubMenu(hMainMenu, 3); - if (Globals.hMDIWnd) - SendMessage(Globals.hMDIWnd, WM_MDISETMENU, - (WPARAM) hMainMenu, - (LPARAM) Globals.hWindowsMenu); - else SetMenu(Globals.hMainWnd, hMainMenu); + /* Remove dummy item */ + RemoveMenu(Globals.hLanguageMenu, 0, MF_BYPOSITION); + /* Add language items */ + for (i = 0; i <= MAX_LANGUAGE_NUMBER; i++) + if (STRING_LoadStringOtherLanguage(i, IDS_LANGUAGE_MENU_ITEM, item, sizeof(item))) + AppendMenu(Globals.hLanguageMenu, MF_STRING | MF_BYCOMMAND, + PM_FIRST_LANGUAGE + i, item); - /* Destroy old menu */ - if (Globals.hMainMenu) DestroyMenu(Globals.hMainMenu); - Globals.hMainMenu = hMainMenu; - } - /* Unsupported language */ - else if(lstrcmp(lang, "En")) STRING_SelectLanguage("En"); - else - { - MessageBox(Globals.hMainWnd, "No language found", "FATAL ERROR", MB_OK); - PostQuitMessage(1); - } + if (Globals.hMDIWnd) + SendMessage(Globals.hMDIWnd, WM_MDISETMENU, + (WPARAM) hMainMenu, + (LPARAM) Globals.hWindowsMenu); + else SetMenu(Globals.hMainWnd, hMainMenu); + + /* Destroy old menu */ + if (Globals.hMainMenu) DestroyMenu(Globals.hMainMenu); + Globals.hMainMenu = hMainMenu; - /* have to be last because of - * the possible recursion */ - Globals.lpszLanguage = lang; #ifdef WINELIB - if (!lstrcmp(lang, "De")) Options.language = LANG_De; - if (!lstrcmp(lang, "En")) Options.language = LANG_En; + /* Update system menus */ + for (i = 0; langNames[i] && lstrcmp(lang, langNames[i]);) i++; + if (langNames[i]) Options.language = i; + GetSystemMenu(Globals.hMainWnd, TRUE); for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup)) diff --git a/resources/Makefile.in b/resources/Makefile.in index 7cb78711e2..dc53de0d51 100644 --- a/resources/Makefile.in +++ b/resources/Makefile.in @@ -2,7 +2,7 @@ TOPSRC = @top_srcdir@ MODULE = resources -LANGUAGES = En Es De No Fr Fi Da Cz Eo +LANGUAGES = En Es De No Fr Fi Da Cz Eo It SYSRES_SRCS = $(LANGUAGES:%=sysres_%.c) diff --git a/resources/TODO b/resources/TODO index 28e4df9e57..db771cc964 100644 --- a/resources/TODO +++ b/resources/TODO @@ -15,3 +15,6 @@ Therefore: Frans van Dorsselaer dorssel@rulhm1.LeidenUniv.nl + + +Robert Pouliot (krynos@qbc.clic.net): Changes to sysres_Fr.rc have been made. diff --git a/resources/sysres.c b/resources/sysres.c index ae1cbd0364..832d0261fe 100644 --- a/resources/sysres.c +++ b/resources/sysres.c @@ -18,6 +18,7 @@ #include "sysres_Da.h" #include "sysres_Cz.h" #include "sysres_Eo.h" +#include "sysres_It.h" static const struct resource * const * SYSRES_Resources[] = @@ -30,7 +31,8 @@ static const struct resource * const * SYSRES_Resources[] = sysres_Fi_Table, /* LANG_Fi */ sysres_Da_Table, /* LANG_Da */ sysres_Cz_Table, /* LANG_Cz */ - sysres_Eo_Table /* LANG_Eo */ + sysres_Eo_Table, /* LANG_Eo */ + sysres_It_Table /* LANG_It */ }; diff --git a/resources/sysres_Fr.rc b/resources/sysres_Fr.rc index 723ea2dd91..3a241bd6fe 100644 --- a/resources/sysres_Fr.rc +++ b/resources/sysres_Fr.rc @@ -165,37 +165,38 @@ FONT 8, "Helv" PUSHBUTTON "Annuler", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP } - -FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 84 +FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Rechercher" FONT 8, "Helv" { - LTEXT "&Rechercher:", 1088, 6, 6, 40, 9 - LTEXT "", 1089, 60, 6, 150, 9 - CHECKBOX "M&ot seulement", 1040, 20, 30, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Respect des &majuscules/minuscules", 1041, 20, 50, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - GROUPBOX "Direction", 1072, 90, 40, 80, 40, BS_GROUPBOX - RADIOBUTTON "&Haut", 1056, 100, 50, 50, 12 - RADIOBUTTON "&Bas", 1057, 150, 50, 50, 12 - DEFPUSHBUTTON "&Poursuivre", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annuler", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "&Rechercher:", -1, 4, 8, 42, 8 + EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + CHECKBOX "M&ot seulement", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Respect des &majuscules/minuscules", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Direction", 1072, 107, 26, 68, 28 + CONTROL "&Haut", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 + CONTROL "&Bas", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 + DEFPUSHBUTTON "&Poursuivre", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annuler", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aide", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP } -REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 114 +REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Remplacer" FONT 8, "Helv" { - LTEXT "&Rechercher:", 1088, 6, 6, 40, 9 - LTEXT "", 1089, 60, 6, 150, 9 - LTEXT "R&emplacer par:", 1090, 6, 26, 40, 9 - LTEXT "", 1091, 60, 26, 150, 9 - CHECKBOX "M&ot seulement", 1040, 20, 40, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - CHECKBOX "Respect des &majuscules/minuscules", 1041, 20, 60, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - DEFPUSHBUTTON "&Poursuivre", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Rempla&cer", 1024, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Remplacer &tout", 1025, 206, 44, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Fermer", 2, 206, 64, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "&Rechercher:", -1, 4, 9, 48, 8 + EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "R&emplacer par:", -1, 4, 26, 48, 8 + EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + CHECKBOX "M&ot seulement", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Respect des &majuscules/minuscules", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + DEFPUSHBUTTON "&Poursuivre", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Rempla&cer", 1024, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Remplacer &tout", 1025, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Fermer", 2, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aide", 1038, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP } diff --git a/resources/sysres_It.rc b/resources/sysres_It.rc new file mode 100644 index 0000000000..15a0136115 --- /dev/null +++ b/resources/sysres_It.rc @@ -0,0 +1,202 @@ +SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE +{ + MENUITEM "&Ripristina", 61728 + MENUITEM "&Muovi", 61456 + MENUITEM "&Dimensione", 61440 + MENUITEM "Mi&nimizza", 61472 + MENUITEM "Ma&ssimizza", 61488 + MENUITEM SEPARATOR + MENUITEM "&Chiudi\tAlt-F4", 61536 + MENUITEM SEPARATOR + MENUITEM "C&ambia a ...\tCtrl-Esc", 61744 + MENUITEM SEPARATOR + MENUITEM "&Info su WINE ...", 61761 +} + +MSGBOX DIALOG 100, 80, 216, 168 +STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +BEGIN + ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE + LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP + PUSHBUTTON "&Ok", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Annulla", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Abbandona", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Riprova", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Ignora", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Si", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 223, 200 +STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Informazioni su %s" +FONT 10, "Sistema" +{ + DEFPUSHBUTTON "OK", 1, 91, 180, 40, 14 + CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 215, 140 + LTEXT "Text", 100, 11, 40, 200, 130, SS_NOPREFIX | WS_GROUP + ICON "", 1088, 195, 10, 18, 20 +} + + +OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Apri" +FONT 8, "Helv" +{ + LTEXT "File &Nome:", 1090, 6, 6, 76, 9 + EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP + LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP + LTEXT "&Directories:", -1, 110, 6, 92, 9 + LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP + LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP + LTEXT "Files di &Tipo:", 1089, 6, 104, 90, 9 + COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP + LTEXT "&Unita':", 1091, 110, 104, 92, 9 + COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Apri", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aiuto", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "Solo &Lettura", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +} + + +SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Salva con nome ..." +FONT 8, "Helv" +{ + LTEXT "File &Nome:", 1090, 6, 6, 76, 9 + EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP + LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP + LTEXT "&Directories:", -1, 110, 6, 92, 9 + LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP + LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP + LTEXT "Files di &Tipo:", 1089, 6, 104, 90, 9 + COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP + LTEXT "&Unita':", 1091, 110, 104, 92, 9 + COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Save As", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cancel", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Help", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP + CHECKBOX "&Read Only", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +} + + +PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Stampa" +FONT 8, "Helv" +{ + LTEXT "Stampante:", 1088, 6, 6, 40, 9 + LTEXT "", 1089, 60, 6, 150, 9 + GROUPBOX "Pagine da stampare", 1072, 6, 30, 160, 65, BS_GROUPBOX + RADIOBUTTON "&Tutte", 1056, 16, 45, 60, 12 + RADIOBUTTON "S&elezione", 1057, 16, 60, 60, 12 + RADIOBUTTON "&Pagine", 1058, 16, 75, 60, 12 + DEFPUSHBUTTON "Stampa", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Configura", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "&Da:", 1090, 60, 80, 30, 9 + LTEXT "&A:", 1091, 120, 80, 30, 9 + LTEXT "&Qualita' di Stampa:", 1092, 6, 100, 76, 9 + COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + CHECKBOX "Stampa su Fi&le", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Condensato", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +} + + +PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configurazione Stampante" +FONT 8, "Helv" +{ + GROUPBOX "Stampante", 1072, 6, 10, 180, 65, BS_GROUPBOX + RADIOBUTTON "Stampante &Preferita", 1056, 16, 20, 80, 12 + LTEXT "[none]", 1088, 35, 35, 120, 9 + RADIOBUTTON "Stampante &Specifica", 1057, 16, 50, 80, 12 + COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Ok", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Installa", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP + GROUPBOX "Orientamento", 1073, 6, 85, 100, 50, BS_GROUPBOX + RADIOBUTTON "&Verticale", 1058, 50, 100, 40, 12 + RADIOBUTTON "&Orizzontale", 1059, 50, 115, 40, 12 + ICON "LANDSCAP", 1097, 10, 95, 32, 32 + ICON "PORTRAIT", 1098, 10, 95, 32, 32 + GROUPBOX "Carta", 1074, 120, 85, 180, 50, BS_GROUPBOX + LTEXT "&Dimensione", 1089, 130, 95, 30, 9 + LTEXT "&Sorgente", 1090, 130, 110, 30, 9 + COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP + COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP +} + + +CHOOSE_FONT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Font" +FONT 8, "Helv" +{ + LTEXT "Font:", 1088, 6, 6, 40, 9 + LTEXT "", 1089, 60, 6, 150, 9 + DEFPUSHBUTTON "Ok", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP +} + + +CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Colore" +FONT 8, "Helv" +{ + LTEXT "Colori di &Base:", 1088, 6, 6, 40, 9 + LTEXT "Colori &Utente:", 1089, 6, 126, 40, 9 + LTEXT "Colore|Sol&ido", 1090, 100, 146, 40, 9 + LTEXT "&Tinta:", 1091, 150, 126, 40, 9 + LTEXT "&Sat:", 1092, 150, 146, 40, 9 + LTEXT "&Lum:", 1093, 150, 166, 40, 9 + LTEXT "&Rosso:", 1094, 150, 126, 40, 9 + LTEXT "&Verde:", 1095, 150, 146, 40, 9 + LTEXT "Bl&u:", 1096, 150, 166, 40, 9 + DEFPUSHBUTTON "Ok", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aggiugni ai Colori Utente", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Cancella Colori Utente", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP +} + + +FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Trova" +FONT 8, "Helv" +{ + LTEXT "Tro&va cosa:", -1, 4, 8, 42, 8 + EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + CHECKBOX "&Parola Intera", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Maiuscole/Minuscole", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP + GROUPBOX "Direzione", 1072, 107, 26, 68, 28 + CONTROL "&Su", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12 + CONTROL "&Giu'", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12 + DEFPUSHBUTTON "&Trova Prossimo", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aiuto", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP +} + + +REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Cambia" +FONT 8, "Helv" +{ + LTEXT "Tro&va cosa:", -1, 4, 9, 48, 8 + EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "Ca&mbia con:", -1, 4, 26, 48, 8 + EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP + CHECKBOX "&Parola Intera", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Maiuscole/Minuscole", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP + DEFPUSHBUTTON "&Trova Prossimo", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Cambia", 1024, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cambia &Tutto", 1025, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Aiuto", 1038, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP +} diff --git a/tools/build-spec.txt b/tools/build-spec.txt index 141a06674b..88887c1204 100644 --- a/tools/build-spec.txt +++ b/tools/build-spec.txt @@ -1,4 +1,5 @@ name NAME +type win16|win32 id ID_NUMBER ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]]) @@ -16,9 +17,10 @@ ORDINAL return EXPORTNAME ARGLENGTH RETVALUE -------------------- General: - "name" and "id" fields are mandatory. Specific ordinal declarations -are optional, but the default handler will print an error message. Lines -whose first character is a '#' will be ignored as comments. + "name", "type" and "id" fields are mandatory. Specific ordinal +declarations are optional, but the default handler will print an error +message. Lines whose first character is a '#' will be ignored as +comments. Variable ordinals: diff --git a/tools/build.c b/tools/build.c index 938f99f8f4..04f7a68e21 100644 --- a/tools/build.c +++ b/tools/build.c @@ -9,6 +9,7 @@ #include #include #include "wine.h" +#include "winerror.h" /* for ERROR_CALL_NOT_IMPLEMENTED */ #include "module.h" #include "neexe.h" #include "windows.h" @@ -31,12 +32,19 @@ #define TYPE_RETURN 8 #define TYPE_STUB 9 #define TYPE_STDCALL 10 -#define TYPE_CDECL 11 #define MAX_ORDINALS 1299 /* Callback function used for stub functions */ -#define STUB_CALLBACK "RELAY_Unimplemented" +#define STUB_CALLBACK \ + ((SpecType == SPEC_WIN16) ? "RELAY_Unimplemented16": "RELAY_Unimplemented32") + +enum SPEC_TYPE +{ + SPEC_INVALID, + SPEC_WIN16, + SPEC_WIN32 +}; typedef struct ordinal_definition_s { @@ -67,8 +75,8 @@ typedef struct ordinal_return_definition_s static ORDDEF OrdinalDefinitions[MAX_ORDINALS]; -char LowerDLLName[80]; -char UpperDLLName[80]; +static enum SPEC_TYPE SpecType = SPEC_INVALID; +char DLLName[80]; int Limit = 0; int DLLId; int Base = 0; @@ -132,16 +140,6 @@ static int IsNumberString(char *s) return 1; } -static char *strlower(char *s) -{ - char *p; - - for(p = s; *p != '\0'; p++) - *p = tolower(*p); - - return s; -} - static char *strupper(char *s) { char *p; @@ -326,8 +324,6 @@ static int ParseExportFunction(int ordinal, int type) fdp->arg_types[i] = 'l'; else if (!strcmp(token, "ptr")) fdp->arg_types[i] = 'p'; - else if (!strcmp(token, "...")) - fdp->arg_types[i] = '.'; else { fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token); @@ -451,8 +447,6 @@ static int ParseOrdinal(int ordinal) return ParseExportFunction(ordinal, TYPE_REGISTER); else if (strcmp(token, "stdcall") == 0) return ParseExportFunction(ordinal, TYPE_STDCALL); - else if (strcmp(token, "cdecl") == 0) - return ParseExportFunction(ordinal, TYPE_CDECL); else if (strcmp(token, "equate") == 0) return ParseEquate(ordinal); else if (strcmp(token, "return") == 0) @@ -476,12 +470,20 @@ static int ParseTopLevel(void) { if (strcmp(token, "name") == 0) { - strcpy(LowerDLLName, GetToken()); - strlower(LowerDLLName); - - strcpy(UpperDLLName, LowerDLLName); - strupper(UpperDLLName); + strcpy(DLLName, GetToken()); + strupper(DLLName); } + else if (strcmp(token, "type") == 0) + { + token = GetToken(); + if (!strcmp(token, "win16" )) SpecType = SPEC_WIN16; + else if (!strcmp(token, "win32" )) SpecType = SPEC_WIN32; + else + { + fprintf(stderr, "%d: Type must be 'win16' or 'win32'\n", Line); + exit(1); + } + } else if (strcmp(token, "id") == 0) { token = GetToken(); @@ -611,8 +613,8 @@ static void BuildModule( int max_code_offset, int max_data_offset ) pModule->fileinfo = (int)pFileInfo - (int)pModule; memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) ); pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) - + strlen(UpperDLLName) + 4; - sprintf( pFileInfo->szPathName, "%s.DLL", UpperDLLName ); + + strlen(DLLName) + 4; + sprintf( pFileInfo->szPathName, "%s.DLL", DLLName ); pstr = (char *)pFileInfo + pFileInfo->cBytes + 1; /* Segment table */ @@ -652,8 +654,8 @@ static void BuildModule( int max_code_offset, int max_data_offset ) pModule->name_table = (int)pstr - (int)pModule; /* First entry is module name */ - *pstr = strlen(UpperDLLName ); - strcpy( pstr + 1, UpperDLLName ); + *pstr = strlen(DLLName ); + strcpy( pstr + 1, DLLName ); pstr += *pstr + 1; *(WORD *)pstr = 0; pstr += sizeof(WORD); @@ -727,8 +729,8 @@ static void BuildModule( int max_code_offset, int max_data_offset ) /* Dump the module content */ printf( "\t.data\n" ); - printf( "\t.globl " PREFIX "%s_Module_Start\n", UpperDLLName ); - printf( PREFIX "%s_Module_Start:\n", UpperDLLName ); + printf( "\t.globl " PREFIX "%s_Module_Start\n", DLLName ); + printf( PREFIX "%s_Module_Start:\n", DLLName ); size = (int)pstr - (int)pModule; for (i = 0, pstr = buffer; i < size; i++, pstr++) { @@ -736,194 +738,113 @@ static void BuildModule( int max_code_offset, int max_data_offset ) printf( "%d%c", *pstr, ((i & 7) != 7) ? ',' : '\n' ); } if (i & 7) printf( "0\n" ); - printf( "\t.globl " PREFIX "%s_Module_End\n", UpperDLLName ); - printf( PREFIX "%s_Module_End:\n", UpperDLLName ); + printf( "\t.globl " PREFIX "%s_Module_End\n", DLLName ); + printf( PREFIX "%s_Module_End:\n", DLLName ); } -static void BuildSpec32Files( char *specname ) +/******************************************************************* + * BuildSpec32Files + * + * Build a Win32 assembly file from a spec file. + */ +static void BuildSpec32Files(void) { ORDDEF *odp; ORDFUNCDEF *fdp; ORDRETDEF *rdp; int i; - int varargs; - SpecFp = fopen( specname, "r"); - if (SpecFp == NULL) - { - fprintf(stderr, "Could not open specification file, '%s'\n", specname); - exit(1); - } - - ParseTopLevel(); - - printf( "/* File generated automatically, do not edit! */\n" ); - printf( "#include \n"); - printf( "#include \n"); - printf( "#include \"windows.h\"\n"); - printf( "#include \"dlls.h\"\n"); - printf( "#include \"pe_image.h\"\n"); - printf( "#include \"winerror.h\"\n"); - printf( "#include \"relay32.h\"\n"); - printf( "#include \"stddebug.h\"\n"); - printf( "#include \"debug.h\"\n"); + printf( "/* File generated automatically; do not edit! */\n" ); + printf( "\t.text\n" ); + printf( "\t.globl " PREFIX "%s_Code_Start\n", DLLName ); + printf( PREFIX "%s_Code_Start:\n\n", DLLName ); odp = OrdinalDefinitions; for (i = 0; i <= Limit; i++, odp++) { - int argno,argc; fdp = odp->additional_data; rdp = odp->additional_data; switch (odp->type) { case TYPE_INVALID: - case TYPE_STUB: - printf( "int %s_%d()\n{\n\t", UpperDLLName, i); - printf( "RELAY32_Unimplemented(\"%s\",%d);\n", UpperDLLName, i); - printf( "\t/*NOTREACHED*/\n\treturn 0;\n}\n\n"); + printf( "/* %s.%d */\n", DLLName, i ); + printf( "\t.align 4\n" ); + printf( "%s_%d:\n", DLLName, i ); + printf( "\tpushl %%ebp\n" ); + printf( "\tpushl $%s_%d_Name\n", DLLName, i ); + printf( "\tpushl $" PREFIX "%s\n", STUB_CALLBACK ); + printf( "\tjmp " PREFIX "Stdcall_0\n" ); + printf( "%s_%d_Name:\n", DLLName, i ); + printf( "\t.ascii \"%s_%d\\0\"\n", DLLName, i ); break; + case TYPE_STDCALL: - case TYPE_CDECL: - varargs=0; - argc=strlen(fdp->arg_types); -#if 0 - if(odp->type == TYPE_STDCALL) - { - /* Output a function prototype with stdcall attribute */ - printf( "void %s_%d(", UpperDLLName, i); - for(argno=0;argnoarg_types[argno]) - { - case 'p': printf( "void *");break; - case 'l': printf( "int ");break; - case '.': printf( "... ");varargs=argno;break; - default: - fprintf(stderr, "Not supported argument type %c\n", - fdp->arg_types[argno]); - exit(1); - } - if(fdp->arg_types[argno]!='.') putchar( 'a'+argno ); - if (argno!=argc-1) putchar( ',' ); - } - printf( ") __attribute((stdcall));\n" ); - } -#endif - printf( "void %s_%d(", UpperDLLName, i); - for(argno=0;argnotype == TYPE_STDCALL) { - switch(fdp->arg_types[argno]) - { - case 'p': printf( "void *");break; - case 'l': printf( "int ");break; - default: - fprintf(stderr, "Not supported argument type %c\n", - fdp->arg_types[argno]); - exit(1); - } - } else { - switch(fdp->arg_types[argno]) - { - case 'p': printf( "void *");break; - case 'l': printf( "int ");break; - case '.': printf( "... ");varargs=argno;break; - default: - fprintf(stderr, "Not supported argument type %c\n", - fdp->arg_types[argno]); - exit(1); - } - } - if(fdp->arg_types[argno]!='.') putchar( 'a'+argno ); - if (argno!=argc-1) putchar( ',' ); - } - printf( ")" ); - printf( "\n{\n" ); - if (varargs) printf( "\tva_list valist;\n\n\tva_start(valist, %c);", - 'a'+varargs-1 ); - printf( "\tdprintf_relay(stddeb,\"Call %%s.%%s("); - for (argno=0;argnoarg_types[argno]!='.') - { - putchar( '%' ); - putchar( (fdp->arg_types[argno] == 'p') ? 'p' : 'x' ); - if (argno < argc-1) putchar( ',' ); - } - printf( ")\\n\", \"%s\", \"%s\"", UpperDLLName, odp->export_name); - for(argno=0;argnoarg_types[argno]!='.') printf( ",%c", 'a'+argno); - printf( ");\n\t%s(", fdp->internal_name ); - for(argno=0;argnoarg_types[argno]=='.') printf("valist"); - else putchar('a'+argno); - if (argno!=argc-1) putchar(','); - } - printf( ");\n"); - if(odp->type == TYPE_STDCALL) { - printf( "\t__asm__ __volatile__ (\"movl %%ebp,%%esp\");\n"); - printf( "\t__asm__ __volatile__ (\"popl %%ebp\");\n"); - printf( "\t__asm__ __volatile__ (\"addl $%d,%%esp\");\n", argc*4+4); - printf( "\t__asm__ __volatile__ (\"jmp -%d(%%esp)\");\n", argc*4+4); - } - printf( "}\n\n"); + case TYPE_STUB: + printf( "/* %s.%d (%s) */\n", + DLLName, i, odp->export_name); + printf( "\t.align 4\n" ); + printf( "%s_%d:\n", DLLName, i ); + printf( "\tpushl %%ebp\n" ); + printf( "\tpushl $%s_%d_Name\n", DLLName, i ); + printf( "\tpushl $" PREFIX "%s\n", fdp->internal_name ); + printf( "\tjmp " PREFIX "Stdcall_%d\n", strlen(fdp->arg_types) ); + printf( "%s_%d_Name:\n", DLLName, i ); + printf( "\t.ascii \"%s\\0\"\n", odp->export_name ); break; + case TYPE_RETURN: - printf( "void %s_%d()\n{\n\t", UpperDLLName, i); - printf( "RELAY32_DebugEnter(\"%s\",\"%s\");\n\t", - UpperDLLName, odp->export_name); - printf( "WIN32_LastError=ERROR_CALL_NOT_IMPLEMENTED;\n"); - printf( "\t__asm__ __volatile__ (\"movl $%d,%%eax\");\n", - rdp->ret_value); - printf( "\t__asm__ __volatile__ (\"movl %%ebp,%%esp;popl %%ebp;" - "ret $%d\");\n}\n\n", rdp->arg_size); + printf( "/* %s.%d (%s) */\n", + DLLName, i, odp->export_name); + printf( "\t.align 4\n" ); + printf( "%s_%d:\n", DLLName, i ); + printf( "\tmovl $%d,%%eax\n", ERROR_CALL_NOT_IMPLEMENTED ); + printf( "\tmovl %%eax," PREFIX "WIN32_LastError\n" ); + printf( "\tmovl $%d,%%eax\n", rdp->ret_value ); + if (rdp->arg_size) printf( "\tret $%d\n", rdp->arg_size ); + else printf( "\tret\n" ); + printf( "%s_%d_Name:\n", DLLName, i ); + printf( "\t.ascii \"%s\\0\"\n", odp->export_name ); break; + default: fprintf(stderr,"build: function type %d not available for Win32\n", odp->type); - break; - } - } - - printf( "static WIN32_function functions[%d+1]={\n", Limit); - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - fdp = odp->additional_data; - rdp = odp->additional_data; - - switch (odp->type) - { - case TYPE_INVALID: - printf( "{0,%s_%d},\n",UpperDLLName, i); - break; - case TYPE_RETURN: - case TYPE_STDCALL: - case TYPE_CDECL: - case TYPE_STUB: - printf( "{\"%s\",%s_%d},\n", odp->export_name, UpperDLLName, i); - break; - default: - fprintf(stderr, "build: implementation error: missing %d\n", - odp->type); exit(1); } } - printf("};\n\n"); - printf( "static WIN32_builtin dll={\"%s\",functions,%d,%d,0};\n", - UpperDLLName, Limit+1, Base); + printf( "\n/* Function table */\n" ); + printf( "\t.globl " PREFIX "%s_Module_Start\n", DLLName ); + printf( PREFIX "%s_Module_Start:\n", DLLName ); - printf( "void %s_Init(void)\n{\n",UpperDLLName); - printf( "\tdll.next=WIN32_builtin_list;\n"); - printf( "\tWIN32_builtin_list=&dll;\n\tRELAY32_MakeFakeModule(&dll);\n}"); + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) + { + if (odp->type == TYPE_INVALID) + printf( "\t.long 0,%s_%d\n", DLLName, i ); + else + printf( "\t.long %s_%d_Name,%s_%d\n", + DLLName, i, DLLName, i ); + } + + printf( "\t.globl " PREFIX "%s_Module_End\n", DLLName ); + printf( PREFIX "%s_Module_End:\n", DLLName ); + printf( "\t.long 0,0\n" ); + + printf( "\t.globl " PREFIX "%s_Data_Start\n", DLLName ); + printf( PREFIX "%s_Data_Start:\n", DLLName ); + printf( "\t.long %d\n", Base ); } -static void BuildSpec16Files( char *specname ) +/******************************************************************* + * BuildSpec16Files + * + * Build a Win16 assembly file from a spec file. + */ +static void BuildSpec16Files(void) { ORDDEF *odp; ORDFUNCDEF *fdp; @@ -931,19 +852,10 @@ static void BuildSpec16Files( char *specname ) int i; int code_offset, data_offset; - SpecFp = fopen( specname, "r"); - if (SpecFp == NULL) - { - fprintf(stderr, "Could not open specification file, '%s'\n", specname); - exit(1); - } - - ParseTopLevel(); - printf( "/* File generated automatically; do not edit! */\n" ); printf( "\t.data\n" ); - printf( "\t.globl " PREFIX "%s_Data_Start\n", UpperDLLName ); - printf( PREFIX "%s_Data_Start:\n", UpperDLLName ); + printf( "\t.globl " PREFIX "%s_Data_Start\n", DLLName ); + printf( PREFIX "%s_Data_Start:\n", DLLName ); #ifdef __svr4__ printf( "\t.4byte 0,0,0,0,0,0,0,0\n" ); #else @@ -951,8 +863,8 @@ static void BuildSpec16Files( char *specname ) #endif data_offset = 16; printf( "\t.text\n" ); - printf( "\t.globl " PREFIX "%s_Code_Start\n", UpperDLLName ); - printf( PREFIX "%s_Code_Start:\n", UpperDLLName ); + printf( "\t.globl " PREFIX "%s_Code_Start\n", DLLName ); + printf( PREFIX "%s_Code_Start:\n", DLLName ); code_offset = 0; odp = OrdinalDefinitions; @@ -972,13 +884,13 @@ static void BuildSpec16Files( char *specname ) break; case TYPE_BYTE: - printf( "/* %s.%d */\n", UpperDLLName, i); + printf( "/* %s.%d */\n", DLLName, i); odp->offset = data_offset; data_offset += OutputVariableCode( ".byte", odp); break; case TYPE_WORD: - printf( "/* %s.%d */\n", UpperDLLName, i); + printf( "/* %s.%d */\n", DLLName, i); odp->offset = data_offset; #ifdef __svr4__ data_offset += 2 * OutputVariableCode( ".4byte", odp); @@ -988,13 +900,13 @@ static void BuildSpec16Files( char *specname ) break; case TYPE_LONG: - printf( "/* %s.%d */\n", UpperDLLName, i); + printf( "/* %s.%d */\n", DLLName, i); odp->offset = data_offset; data_offset += 4 * OutputVariableCode( ".long", odp); break; case TYPE_RETURN: - printf( "/* %s.%d */\n", UpperDLLName, i); + printf( "/* %s.%d */\n", DLLName, i); printf( "\tmovw $%d,%%ax\n", rdp->ret_value & 0xffff ); printf( "\tmovw $%d,%%dx\n", (rdp->ret_value >> 16) & 0xffff); printf( "\t.byte 0x66\n"); @@ -1011,7 +923,7 @@ static void BuildSpec16Files( char *specname ) case TYPE_PASCAL: case TYPE_PASCAL_16: case TYPE_STUB: - printf( "/* %s.%d */\n", UpperDLLName, i); + printf( "/* %s.%d */\n", DLLName, i); printf( "\tpushw %%bp\n" ); printf( "\tpushl $0x%08x\n", (DLLId << 16) | i); printf( "\tpushl $" PREFIX "%s\n", fdp->internal_name ); @@ -1030,8 +942,9 @@ static void BuildSpec16Files( char *specname ) break; default: - fprintf( stderr, "build: Unknown function type; please report.\n"); - break; + fprintf(stderr,"build: function type %d not available for Win16\n", + odp->type); + exit(1); } } @@ -1045,6 +958,36 @@ static void BuildSpec16Files( char *specname ) } +/******************************************************************* + * BuildSpecFiles + * + * Build an assembly file from a spec file. + */ +static void BuildSpecFiles( char *specname ) +{ + SpecFp = fopen( specname, "r"); + if (SpecFp == NULL) + { + fprintf(stderr, "Could not open specification file, '%s'\n", specname); + exit(1); + } + + ParseTopLevel(); + switch(SpecType) + { + case SPEC_INVALID: + fprintf( stderr, "%s: Missing 'type' declaration\n", specname ); + exit(1); + case SPEC_WIN16: + BuildSpec16Files(); + break; + case SPEC_WIN32: + BuildSpec32Files(); + break; + } +} + + /******************************************************************* * BuildCall32LargeStack * @@ -1718,11 +1661,102 @@ static void BuildRet16Func() } +/******************************************************************* + * BuildStdcallFunc + * + * Build a stdcall call-back function. 'args' is the number of dword arguments. + * + * Stack layout: + * ... ... + * (ebp+12) arg2 + * (ebp+8) arg1 + * (ebp+4) ret addr + * (ebp) ebp + * (ebp-4) func name + * (ebp-8) entry point + */ +static void BuildStdcallFunc( int args ) +{ + /* Function header */ + + printf( "/**********\n" ); + printf( " * " PREFIX "Stdcall_%d\n", args ); + printf( " **********/\n" ); + printf( "\t.align 4\n" ); + printf( "\t.globl " PREFIX "Stdcall_%d\n\n", args ); + printf( PREFIX "Stdcall_%d:\n", args ); + + /* Entry code */ + + printf( "\tleal 8(%%esp),%%ebp\n" ); + +#if 0 + /* Switch to the internal stack */ + + printf( "\tpushl " PREFIX "IF1632_Saved32_esp\n" ); + printf( "\tmovl %%esp, " PREFIX "IF1632_Saved32_esp\n" ); + printf( "\tmovl " PREFIX "IF1632_Original32_esp, %%esp\n" ); +#endif + + /* Print the debugging info */ + + if (debugging) + { + printf( "\tpushl $%d\n", args ); + printf( "\tcall " PREFIX "RELAY_DebugStdcall\n" ); + printf( "\tadd $4, %%esp\n" ); + } + + /* Transfer the arguments */ + + if (args) + { + int i; + for (i = args; i > 0; i--) printf( "\tpushl %d(%%ebp)\n", 4 * i + 4 ); + } + else + { + /* Push the address of the arguments. The called function will */ + /* ignore this if it really takes no arguments. */ + printf( "\tleal 8(%%ebp),%%eax\n" ); + printf( "\tpushl %%eax\n" ); + } + + /* Call the function */ + + printf( "\tcall -8(%%ebp)\n" ); + + /* Print the debugging info */ + + if (debugging) + { + printf( "\tadd $%d,%%esp\n", args ? (args * 4) : 4 ); + printf( "\tpushl %%eax\n" ); + printf( "\tcall " PREFIX "RELAY_DebugStdcallRet\n" ); + printf( "\tpopl %%eax\n" ); + } + + /* Switch back to the normal stack */ + +#if 0 + printf( "\tmovl -12(%%ebp)," PREFIX "IF1632_Saved32_esp\n" ); +#endif + printf( "\tmovl %%ebp,%%esp\n" ); + printf( "\tpopl %%ebp\n" ); + + /* Return, removing arguments */ + + if (args) printf( "\tret $%d\n", args * 4 ); + else printf( "\tret\n" ); +} + + static void usage(void) { fprintf(stderr, "usage: build -spec SPECNAMES\n" " build -call32 FUNCTION_PROFILES\n" - " build -call16 FUNCTION_PROFILES\n" ); + " build -call16 FUNCTION_PROFILES\n" + " build -stdcall FUNCTION_PROFILES\n" ); exit(1); } @@ -1733,13 +1767,9 @@ int main(int argc, char **argv) if (argc <= 2) usage(); - if (!strcmp( argv[1], "-spec16" )) + if (!strcmp( argv[1], "-spec" )) { - for (i = 2; i < argc; i++) BuildSpec16Files( argv[i] ); - } - else if (!strcmp( argv[1], "-spec32" )) - { - for (i = 2; i < argc; i++) BuildSpec32Files( argv[i] ); + for (i = 2; i < argc; i++) BuildSpecFiles( argv[i] ); } else if (!strcmp( argv[1], "-call32" )) /* 32-bit callbacks */ { @@ -1788,6 +1818,17 @@ int main(int argc, char **argv) printf( "\t.globl " PREFIX "CALL16_End\n" ); printf( PREFIX "CALL16_End:\n" ); } + else if (!strcmp( argv[1], "-stdcall" )) /* stdcall callbacks */ + { + /* File header */ + + printf( "/* File generated automatically. Do not edit! */\n\n" ); + printf( "\t.text\n" ); + + /* Build the callback functions */ + + for (i = 2; i < argc; i++) BuildStdcallFunc( atoi(argv[i]) ); + } else usage(); return 0; diff --git a/win32/advapi.c b/win32/advapi.c index e60c784b1c..c6fc1373e6 100644 --- a/win32/advapi.c +++ b/win32/advapi.c @@ -13,7 +13,7 @@ #include "debug.h" /*********************************************************************** - * GetUserNameA (ADVAPI32.67) + * GetUserNameA [ADVAPI32.67] */ BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize) @@ -31,51 +31,3 @@ BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize) strcpy(lpszName, name); return 1; } - -/*********************************************************************** - * RegCreateKeyEx (ADVAPI32.130) - */ -LONG RegCreateKey(HKEY,LPCTSTR,LPHKEY); -WINAPI LONG RegCreateKeyEx(HKEY key, - const char *subkey, - long dontuse, - const char *keyclass, - DWORD options, - REGSAM sam, - SECURITY_ATTRIBUTES *atts, - HKEY *res, - DWORD *disp) -{ - /* ahum */ - return RegCreateKey(key, subkey, res); -} - -/*********************************************************************** - * RegSetValueEx (ADVAPI32.169) - */ - -WINAPI LONG RegSetValueEx (HKEY key, - const char *name, - DWORD dontuse, - DWORD type, - const void* data, - DWORD len - ) -{ - return 0; -} - -/*********************************************************************** - * RegQueryValueEx (ADVAPI32.157) - */ - -WINAPI LONG RegQueryValueEx(HKEY key, - const char *subkey, - DWORD dontuse, - DWORD *type, - void *ptr, - DWORD *len) -{ - return 0; -} - diff --git a/win32/except.c b/win32/except.c index 45188ce936..e789cf815f 100644 --- a/win32/except.c +++ b/win32/except.c @@ -39,11 +39,18 @@ #include "stddebug.h" #include "debug.h" #include "except.h" +#include "relay32.h" WINAPI DWORD KERNEL32_537(PEXCEPTION_POINTERS ptrs); -LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler= - (LPTOP_LEVEL_EXCEPTION_FILTER) KERNEL32_537; +LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler = NULL; + +void EXC_Init(void) +{ + WIN32_builtin *dll = RELAY32_GetBuiltinDLL("KERNEL32"); + pTopExcHandler = (LPTOP_LEVEL_EXCEPTION_FILTER)RELAY32_GetEntryPoint( dll, + "UnhandledExceptionFilter", 537 ); +} /* * EXC_RtlUnwind diff --git a/win32/init.c b/win32/init.c index fa923b20d3..6de4c20a49 100644 --- a/win32/init.c +++ b/win32/init.c @@ -11,6 +11,7 @@ #include "winerror.h" #include "kernel32.h" #include "handle32.h" +#include "except.h" #include "pe_image.h" #include "task.h" #include "stddebug.h" @@ -111,6 +112,11 @@ VOID GetStartupInfoA(LPSTARTUPINFO lpStartupInfo) */ int KERN32_Init(void) { +#ifndef WINELIB + /* Initialize exception handling */ + EXC_Init(); +#endif + /* Create the standard system handles */ if(CreateStdHandles() != 0) diff --git a/win32/string32.c b/win32/string32.c index e09042a154..66e243e2ec 100644 --- a/win32/string32.c +++ b/win32/string32.c @@ -14,7 +14,8 @@ #include "string32.h" #include "xmalloc.h" -int STRING32_UniLen(LPWSTR s) +int +STRING32_UniLen(LPCWSTR s) { int i; for(i=0;*s;s++) @@ -38,11 +39,18 @@ void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src) *dest = *src; } -void STRING32_AnsiToUni(LPWSTR dest,LPCSTR src) -{ - while(*src) - *dest++=*src++; - *dest = *src; +/* FIXME: we need to use unsigned char here, for if + * we got chars with the 7th bit set, we will get + * negative integers -> wrong unicode values + */ +void +STRING32_AnsiToUni(LPWSTR dest,LPCSTR src) { + unsigned char *usrc; + + usrc=(unsigned char*)src; + while(*usrc) + *dest++=*usrc++; + *dest = *usrc; } LPSTR STRING32_DupUniToAnsi(LPCWSTR src) @@ -92,3 +100,39 @@ int STRING32_lstrcmpniW(LPCWSTR a,LPCWSTR b,DWORD len) } return 0; } + +int +STRING32_lstrcmpW(LPCWSTR a,LPCWSTR b) { + WCHAR diff; + + while(*a && *b) { + diff=*a-*b; + if (diff) return diff; + a++; + b++; + } + if (*a) return *a; + if (*b) return -*b; + return 0; +} + +LPWSTR +STRING32_lstrchrW(LPCWSTR a,WCHAR c) { + while(*a) { + if (*a==c) + return a; + a++; + } + return NULL; +} + +LPWSTR +STRING32_strdupW(LPCWSTR a) { + LPWSTR b; + int len; + + len=sizeof(WCHAR)*(STRING32_UniLen(a)+1); + b=(LPWSTR)xmalloc(len); + memcpy(b,a,len); + return b; +} diff --git a/win32/user32.c b/win32/user32.c index 42a45821ba..b9a9db5c05 100644 --- a/win32/user32.c +++ b/win32/user32.c @@ -9,6 +9,7 @@ #include #include +#include #include "windows.h" #include "winerror.h" #include "relay32.h" @@ -527,3 +528,8 @@ int USER32_DialogBoxParamA(HINSTANCE hInstance,LPCSTR lpszName, if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent); return -1; } + +int USER32_wsprintfA( int *args ) +{ + return vsprintf( (char *)args[0], (char *)args[1], (va_list)&args[2] ); +} diff --git a/windows/alias.c b/windows/alias.c index df873193fb..57160940b5 100644 --- a/windows/alias.c +++ b/windows/alias.c @@ -7,6 +7,7 @@ #include "windows.h" #include "alias.h" +#include "module.h" #include "stddebug.h" #include "debug.h" @@ -22,6 +23,22 @@ static int LastRecord; int ALIAS_UseAliases; +/* Aliased window procedures */ +extern LRESULT ButtonWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT StaticWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT ScrollBarWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT ListBoxWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT ComboBoxWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT ComboLBoxWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT EditWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT PopupMenuWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT DesktopWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT DefDlgProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT MDIClientWndProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT AboutDlgProc( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT CARET_Callback( HWND, UINT, WPARAM, LPARAM ); +extern LRESULT SystemMessageBoxProc( HWND, UINT, WPARAM, LPARAM ); + /* closed hashing */ static int ALIAS_LocateHash(DWORD value) { @@ -41,6 +58,48 @@ static int ALIAS_LocateHash(DWORD value) return hash; } + +/*********************************************************************** + * ALIAS_RegisterWndProcAlias + */ +static void ALIAS_RegisterWndProcAlias( DWORD Wine, const char *name ) +{ + FARPROC Win16Proc, Win32Proc; + + Win16Proc = MODULE_GetWndProcEntry16( name ); + Win32Proc = MODULE_GetWndProcEntry32( name ); + ALIAS_RegisterAlias( Wine, (DWORD)Win16Proc, (DWORD)Win32Proc ); +} + + +/*********************************************************************** + * ALIAS_Init + * + * Create aliases for the standard window procedures. + */ +BOOL ALIAS_Init(void) +{ + ALIAS_RegisterWndProcAlias( (DWORD)ButtonWndProc, "ButtonWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)StaticWndProc, "StaticWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)ScrollBarWndProc, "ScrollBarWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)ListBoxWndProc, "ListBoxWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)ComboBoxWndProc, "ComboBoxWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)ComboLBoxWndProc, "ComboLBoxWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)EditWndProc, "EditWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)PopupMenuWndProc, "PopupMenuWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)DesktopWndProc, "DesktopWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)DefDlgProc, "DefDlgProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)MDIClientWndProc, "MDIClientWndProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)AboutDlgProc, "AboutDlgProc" ); + ALIAS_RegisterWndProcAlias( (DWORD)CARET_Callback, "CARET_Callback" ); + ALIAS_RegisterWndProcAlias( (DWORD)SystemMessageBoxProc, "SystemMessageBoxProc" ); + return TRUE; +} + + +/*********************************************************************** + * ALIAS_RegisterAlias + */ void ALIAS_RegisterAlias(DWORD Wine,DWORD Win16, DWORD Win32) { int whash = 0, w16hash = 0, w32hash = 0, recno=0; diff --git a/windows/caret.c b/windows/caret.c index b753d86218..294fac5c1e 100644 --- a/windows/caret.c +++ b/windows/caret.c @@ -6,9 +6,7 @@ */ #include "windows.h" -#include "selectors.h" -#include "alias.h" -#include "relay32.h" +#include "module.h" #include "stddebug.h" /* #define DEBUG_CARET */ #include "debug.h" @@ -88,7 +86,7 @@ void CARET_SetTimer(void) { if (Caret.timerid) KillSystemTimer((HWND)0, Caret.timerid); Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout, - (FARPROC)GetWndProcEntry16("CARET_Callback")); + MODULE_GetWndProcEntry16("CARET_Callback")); } @@ -101,7 +99,7 @@ void CARET_ResetTimer(void) { KillSystemTimer((HWND)0, Caret.timerid); Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout, - (FARPROC)GetWndProcEntry16("CARET_Callback")); + MODULE_GetWndProcEntry16("CARET_Callback")); } } @@ -119,27 +117,6 @@ void CARET_KillTimer(void) } -/***************************************************************** - * CARET_Initialize - */ -static void CARET_Initialize() -{ - DWORD WineProc,Win16Proc,Win32Proc; - static int initialized=0; - - if(!initialized) - { - WineProc = (DWORD)CARET_Callback; - Win16Proc = (DWORD)GetWndProcEntry16("CARET_Callback"); - Win32Proc = (DWORD)RELAY32_GetEntryPoint( - RELAY32_GetBuiltinDLL("WINPROCS32"), - "CARET_Callback", 0); - ALIAS_RegisterAlias(WineProc, Win16Proc, Win32Proc); - initialized=1; - } -} - - /***************************************************************** * CreateCaret (USER.163) */ @@ -176,9 +153,6 @@ BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height) Caret.y = 0; Caret.timeout = GetProfileInt( "windows", "CursorBlinkRate", 750 ); - - CARET_Initialize(); - return TRUE; } diff --git a/windows/defwnd.c b/windows/defwnd.c index 530c5e5fed..d081f22ae5 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -21,7 +21,11 @@ /* Last COLOR id */ #define COLOR_MAX COLOR_BTNHIGHLIGHT -static short iMenuKey = 0; + /* bits in the dwKeyData */ +#define KEYDATA_ALT 0x2000 +#define KEYDATA_PREVSTATE 0x4000 + +static short iF10Key = 0; static short iMenuSysKey = 0; /*********************************************************************** @@ -73,7 +77,7 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) case WM_PAINTICON: case WM_NCPAINT: - return NC_HandleNCPaint( hwnd ); + return NC_HandleNCPaint( hwnd, (HRGN)wParam ); case WM_NCHITTEST: { @@ -246,7 +250,7 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) case WM_SETTEXT: DEFWND_SetText( hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam) ); - NC_HandleNCPaint( hwnd ); /* Repaint caption */ + NC_HandleNCPaint( hwnd , (HRGN)1 ); /* Repaint caption */ return 0; case WM_SETCURSOR: @@ -257,47 +261,77 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) return NC_HandleSetCursor( hwnd, wParam, lParam ); case WM_SYSCOMMAND: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - return NC_HandleSysCommand( hwnd, wParam, pt ); - } - + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + return NC_HandleSysCommand( hwnd, wParam, pt ); + } case WM_KEYDOWN: - if(wParam == VK_F10) iMenuKey = VK_F10; + if(wParam == VK_F10) iF10Key = VK_F10; break; case WM_SYSKEYDOWN: - /* this breaks current pseudo accelerators but - creates a basis for implementing real ones */ - if(wParam == VK_F10) - { - iMenuKey = VK_F10; - break; - } - - if (wParam == VK_MENU) - { - iMenuSysKey = (iMenuSysKey)? 0: 1; - iMenuKey = 0; - } + if( HIWORD(lParam) & KEYDATA_ALT ) + { + /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */ + if( wParam == VK_MENU && !iMenuSysKey ) + iMenuSysKey = 1; + else + iMenuSysKey = 0; + + iF10Key = 0; + + } + else if( wParam == VK_F10 ) + iF10Key = 1; + else + if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 ) + SendMessage( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, + (LPARAM)VK_SPACE); break; case WM_KEYUP: case WM_SYSKEYUP: - if( (wParam == VK_MENU && iMenuSysKey) || - (wParam == VK_F10 && iMenuKey) ) + /* Press and release F10 or ALT */ + + if( ( wParam == VK_MENU && iMenuSysKey ) + || ( wParam == VK_F10 && iF10Key ) ) - /* Send to WS_OVERLAPPED parent. TODO: Handle MDI */ SendMessage( WIN_GetTopParent(hwnd), WM_SYSCOMMAND, SC_KEYMENU, 0L ); - iMenuSysKey = 0; - iMenuKey = 0; + iMenuSysKey = iF10Key = 0; break; + case WM_SYSCHAR: + + iMenuSysKey = 0; + + if( wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE) ) + { + PostMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L ); + break; + } + + if( (HIWORD(lParam) & KEYDATA_ALT) && wParam ) + { + if( wParam == VK_TAB || wParam == VK_ESCAPE ) + break; + + if( wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD) ) + SendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam ); + else + SendMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam ); + } + else + /* check for Ctrl-Esc */ + if( wParam != VK_ESCAPE ) + MessageBeep(0); + + break; + case WM_SHOWWINDOW: if( !lParam ) return 0; /* sent from ShowWindow */ diff --git a/windows/dialog.c b/windows/dialog.c index 793cffb941..a3fc33da40 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -655,6 +655,9 @@ BOOL IsDialogMessage( HWND hwndDlg, LPMSG msg ) #endif } break; + + default: + TranslateMessage( msg ); } break; /* case WM_KEYDOWN */ diff --git a/windows/event.c b/windows/event.c index eba633f723..19fa10a0d2 100644 --- a/windows/event.c +++ b/windows/event.c @@ -54,8 +54,12 @@ BOOL MouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE }; BOOL AsyncMouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE }; BYTE KeyStateTable[256]; BYTE AsyncKeyStateTable[256]; -static WORD ALTKeyState; -static HWND captureWnd = 0; + + + WPARAM lastEventChar = 0; /* this will have to be changed once + * ToAscii starts working */ + +static HWND captureWnd = 0; static BOOL InputEnabled = TRUE; /* Keyboard translation tables */ @@ -114,7 +118,8 @@ typedef union unsigned long count : 16; unsigned long code : 8; unsigned long extended : 1; - unsigned long : 4; + unsigned long : 2; + unsigned long reserved : 2; unsigned long context : 1; unsigned long previous : 1; unsigned long transition : 1; @@ -303,10 +308,11 @@ static void EVENT_key( XKeyEvent *event ) KEYLP keylp; BOOL extended = FALSE; - int count = XLookupString(event, Str, 1, &keysym, &cs); - Str[count] = '\0'; - dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", - keysym, count, Str[0], Str); + int ascii_chars = XLookupString(event, Str, 1, &keysym, &cs); + + Str[ascii_chars] = '\0'; + dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, ascii chars=%u / %X / '%s'\n", + keysym, ascii_chars, Str[0], Str); /* Ctrl-Alt-Return enters the debugger */ if ((keysym == XK_Return) && (event->type == KeyPress) && @@ -343,60 +349,59 @@ static void EVENT_key( XKeyEvent *event ) } else if (key_type == 0) /* character key */ { - if (isalnum(key)) - vkey = toupper(key); /* convert lower to uppercase */ - else - vkey = 0xbe; + if ( isalnum(key) ) + vkey = toupper(key); /* convert lower to uppercase */ + else + vkey = 0xbe; } if (event->type == KeyPress) { - if (vkey == VK_MENU) ALTKeyState = TRUE; - if (!(KeyStateTable[vkey] & 0x0f)) - KeyStateTable[vkey] ^= 0x80; - KeyStateTable[vkey] |= 0x01; + if (!(KeyStateTable[vkey] & 0x80)) + KeyStateTable[vkey] ^= 0x01; + KeyStateTable[vkey] |= 0x80; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode) - 8; keylp.lp1.extended = (extended ? 1 : 0); - keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); + keylp.lp1.reserved = (ascii_chars ? 1 : 0); + keylp.lp1.context = ( (event->state & Mod1Mask) || + (KeyStateTable[VK_MENU] & 0x80)) ? 1 : 0; keylp.lp1.previous = (KeyDown ? 0 : 1); keylp.lp1.transition = 0; dprintf_key(stddeb," wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]); - hardware_event( ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, + hardware_event( KeyStateTable[VK_MENU] & 0x80 ? WM_SYSKEYDOWN : WM_KEYDOWN, vkey, keylp.lp2, event->x_root - desktopX, event->y_root - desktopY, event->time, 0 ); KeyDown = TRUE; - /* The key translation ought to take place in TranslateMessage(). - * However, there is no way of passing the required information - * in a Windows message, so TranslateMessage does not currently - * do anything and the translation is done here. + /* Currently we use reserved field in the scan-code byte to + * make it possible for TranslateMessage to recognize character keys + * and get them from lastEventChar global variable. + * + * ToAscii should handle it. */ - if (count == 1) /* key has an ASCII representation */ - { - dprintf_key(stddeb,"WM_CHAR : wParam=%X\n", (WORD)Str[0] ); - PostMessage( GetFocus(), WM_CHAR, (WORD)(unsigned char)(Str[0]), - keylp.lp2 ); - } + + if( ascii_chars ) lastEventChar = Str[0]; } else { - if (vkey == VK_MENU) ALTKeyState = FALSE; - KeyStateTable[vkey] &= 0xf0; + UINT sysKey = KeyStateTable[VK_MENU]; + + KeyStateTable[vkey] &= ~0x80; keylp.lp1.count = 1; keylp.lp1.code = LOBYTE(event->keycode) - 8; keylp.lp1.extended = (extended ? 1 : 0); + keylp.lp1.reserved = 0; keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); keylp.lp1.previous = 1; keylp.lp1.transition = 1; dprintf_key(stddeb," wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]); - hardware_event( ((ALTKeyState || vkey == VK_MENU) ? - WM_SYSKEYUP : WM_KEYUP), + hardware_event( sysKey & 0x80 ? WM_SYSKEYUP : WM_KEYUP, vkey, keylp.lp2, event->x_root - desktopX, event->y_root - desktopY, event->time, 0 ); diff --git a/windows/keyboard.c b/windows/keyboard.c index 0c1ae3e4ab..bdf8030ff4 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -15,8 +15,10 @@ extern BYTE AsyncKeyStateTable[256]; /********************************************************************** * GetKeyState [USER.106] */ -int GetKeyState(int keycode) +INT GetKeyState(INT keycode) { + INT retval; + switch(keycode) { case VK_LBUTTON: return MouseButtonsStates[0]; @@ -25,8 +27,11 @@ int GetKeyState(int keycode) case VK_RBUTTON: return MouseButtonsStates[2]; default: - return KeyStateTable[keycode]; + retval = ( (INT)(KeyStateTable[keycode] & 0x80) << 8 ) | + (INT)(KeyStateTable[keycode] & 0x01); } + + return retval; } /********************************************************************** diff --git a/windows/mdi.c b/windows/mdi.c index f3f80003d0..a22d1deb49 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -174,7 +174,10 @@ HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, WORD wTo ) if (!wTo || !pWndLast) return 0; break; } - if ((pWnd->dwStyle & WS_VISIBLE) && + + /* we are not interested in owned popups */ + if ( !pWnd->owner && + (pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED)) /* found one */ { pWndLast = pWnd; @@ -782,7 +785,7 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild) hSysPopup = GetSystemMenu(hChild,FALSE); - dprintf_mdi(stddeb,"got popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu); + dprintf_mdi(stddeb,"\t\tgot popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu); if( !InsertMenu(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP, hSysPopup, (SEGPTR)(DWORD)ci->obmClose) ) @@ -795,6 +798,10 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild) return 0; } + /* FIXME: add a call to function that sets sysmenu items according + * to the window state. WS_MAXIMIZE -> no SC_SIZE, etc... + */ + EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); @@ -823,6 +830,10 @@ BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild) child->dwStyle |= WS_SYSMENU; + /* FIXME: add a call to function that sets sysmenu items according + * to the window state. WS_MAXIMIZE -> no SC_SIZE, etc... + */ + RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION); DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION); @@ -1057,9 +1068,25 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_PARENTNOTIFY: - if (wParam == WM_LBUTTONDOWN && (ci->hwndHitTest != ci->hwndActiveChild) ) - SetWindowPos(ci->hwndHitTest, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); - break; + if( wParam == WM_LBUTTONDOWN ) + { + LPPOINT lppt = (LPPOINT)(void*)(&lParam); + HWND child = ChildWindowFromPoint(hwnd, *lppt); + + dprintf_mdi(stddeb,"MDIClient: notification from %04x (%i,%i)\n",child,lppt->x,lppt->y); + + if( child && child != hwnd ) + { + WND* wnd = WIN_FindWndPtr( child ); + + /* if we got owned popup */ + if( wnd->owner ) child = wnd->owner->hwndSelf; + + if( child != ci->hwndActiveChild ) + SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); + } + } + return 0; case WM_SIZE: if( ci->flagChildMaximized ) @@ -1178,10 +1205,6 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { - case WM_NCHITTEST: - ci->hwndHitTest = hwnd; - break; - case WM_SETTEXT: DefWindowProc(hwnd, message, wParam, lParam); MDI_MenuModifyItem(clientWnd,hwnd); @@ -1291,6 +1314,12 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_MENUCHAR: + + /* MDI children don't have menus */ + PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, + (WPARAM)SC_KEYMENU, (LPARAM)wParam); + return 0x00010000L; + case WM_NEXTMENU: /* set current menu to child system menu */ @@ -1321,18 +1350,21 @@ BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg) if( wnd->dwStyle & WS_DISABLED ) return 0; - if( GetKeyState(VK_CONTROL) && !GetKeyState(VK_MENU) ) + if ((GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000)) switch( msg->wParam ) { case VK_F6: case VK_SEPARATOR: - wParam = (GetKeyState(VK_SHIFT))? SC_NEXTWINDOW: SC_PREVWINDOW; + wParam = ( GetKeyState(VK_SHIFT) & 0x8000 )? SC_NEXTWINDOW: SC_PREVWINDOW; break; case VK_RBUTTON: wParam = SC_CLOSE; + break; default: return 0; } + else + return 0; dprintf_mdi(stddeb,"TranslateMDISysAccel: wParam = %04x\n", wParam); diff --git a/windows/message.c b/windows/message.c index 415f39cc40..6a88fc6eb0 100644 --- a/windows/message.c +++ b/windows/message.c @@ -26,10 +26,13 @@ #define HWND_BROADCAST ((HWND)0xffff) +extern BYTE* KeyStateTable; /* event.c */ +extern WPARAM lastEventChar; /* event.c */ + extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove ); /* timer.c */ -DWORD MSG_WineStartTicks; /* Ticks at Wine startup */ +DWORD MSG_WineStartTicks; /* Ticks at Wine startup */ static WORD doubleClickSpeed = 452; @@ -180,8 +183,11 @@ static BOOL MSG_TranslateKeyboardMsg( MSG *msg, BOOL remove ) { /* Send the message to the active window instead, */ /* translating messages to their WM_SYS equivalent */ + msg->hwnd = GetActiveWindow(); - msg->message += WM_SYSKEYDOWN - WM_KEYDOWN; + + if( msg->message < WM_SYSKEYDOWN ) + msg->message += WM_SYSKEYDOWN - WM_KEYDOWN; } return !HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE, msg->wParam, msg->lParam ); @@ -383,6 +389,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, { int pos, mask; MESSAGEQUEUE *msgQueue; + HQUEUE hQueue; LONG nextExp; /* Next timer expiration time */ #ifdef CONFIG_IPC @@ -403,7 +410,8 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, while(1) { - msgQueue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ); + hQueue = GetTaskQueue(0); + msgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ); if (!msgQueue) return FALSE; /* First handle a message put by SendMessage() */ @@ -461,11 +469,24 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, /* Now find a WM_PAINT message */ if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT)) { - msg->hwnd = WIN_FindWinToRepaint( hwnd ); + msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue ); msg->message = WM_PAINT; msg->wParam = 0; msg->lParam = 0; - if (msg->hwnd != 0) break; + if( msg->hwnd && + (!hwnd || msg->hwnd == hwnd || IsChild(hwnd,msg->hwnd)) ) + { + WND* wndPtr = WIN_FindWndPtr(msg->hwnd); + + /* FIXME: WM_PAINTICON should be sent sometimes */ + + if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate) + { + wndPtr->flags &= ~WIN_INTERNAL_PAINT; + QUEUE_DecPaintCount( hQueue ); + } + break; + } } /* Finally handle WM_TIMER messages */ @@ -547,10 +568,14 @@ BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) */ BOOL GetMessage( SEGPTR msg, HWND hwnd, UINT first, UINT last ) { - MSG_PeekMessage( (MSG *)PTR_SEG_TO_LIN(msg), + MSG* lpmsg = (MSG *)PTR_SEG_TO_LIN(msg); + MSG_PeekMessage( lpmsg, hwnd, first, last, PM_REMOVE, FALSE ); + + dprintf_msg(stddeb,"message %04x, hwnd %04x, filter(%04x - %04x)\n", lpmsg->message, + hwnd, first, last ); HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)msg ); - return (((MSG *)PTR_SEG_TO_LIN(msg))->message != WM_QUIT); + return (lpmsg->message != WM_QUIT); } @@ -697,16 +722,35 @@ void WaitMessage( void ) /*********************************************************************** * TranslateMessage (USER.113) + * + * This should call ToAscii but it is currently broken */ + +#define ASCII_CHAR_HACK 0x0800 + BOOL TranslateMessage( LPMSG msg ) { - int message = msg->message; + UINT message = msg->message; + /* BYTE wparam[2]; */ if ((message == WM_KEYDOWN) || (message == WM_KEYUP) || (message == WM_SYSKEYDOWN) || (message == WM_SYSKEYUP)) { - dprintf_msg(stddeb, "Translating key message\n" ); - return TRUE; + dprintf_msg(stddeb, "Translating key %04x, scancode %04x\n", msg->wParam, + HIWORD(msg->lParam) ); + + if( HIWORD(msg->lParam) & ASCII_CHAR_HACK ) + + /* if( ToAscii( msg->wParam, HIWORD(msg->lParam), (LPSTR)&KeyStateTable, + wparam, 0 ) ) + */ + { + message += 2 - (message & 0x0001); + + PostMessage( msg->hwnd, message, lastEventChar, msg->lParam ); + + return TRUE; + } } return FALSE; } diff --git a/windows/msgbox.c b/windows/msgbox.c index 33ebe2cc25..c8215fdc6a 100644 --- a/windows/msgbox.c +++ b/windows/msgbox.c @@ -7,9 +7,7 @@ #include "windows.h" #include "dlgs.h" -#include "selectors.h" -#include "alias.h" -#include "relay32.h" +#include "module.h" #include "win.h" #include "resource.h" #include "task.h" @@ -185,27 +183,16 @@ int MessageBox(HWND hWnd, LPCSTR text, LPCSTR title, WORD type) MSGBOX mbox; int ret; DWORD WineProc,Win16Proc,Win32Proc; - static int initialized = 0; mbox.title = title; mbox.text = text; mbox.type = type; - if (!initialized) - { - WineProc=(DWORD)SystemMessageBoxProc; - Win16Proc=(DWORD)GetWndProcEntry16("SystemMessageBoxProc"); - Win32Proc=(DWORD)RELAY32_GetEntryPoint(RELAY32_GetBuiltinDLL("WINPROCS32"), - "SystemMessageBoxProc",0); - ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc); - initialized=1; - } - handle = SYSRES_LoadResource( SYSRES_DIALOG_MSGBOX ); if (!handle) return 0; ret = DialogBoxIndirectParam( WIN_GetWindowInstance(hWnd), handle, hWnd, - GetWndProcEntry16("SystemMessageBoxProc"), + MODULE_GetWndProcEntry16("SystemMessageBoxProc"), (LONG)&mbox ); SYSRES_FreeResource( handle ); return ret; diff --git a/windows/nonclient.c b/windows/nonclient.c index 70b8125d5e..c94ca9c573 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -18,6 +18,7 @@ #include "scroll.h" #include "nonclient.h" #include "graphics.h" +#include "queue.h" #include "selectors.h" #include "stackframe.h" #include "stddebug.h" @@ -618,18 +619,22 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, /*********************************************************************** * NC_DoNCPaint * - * Paint the non-client area. + * Paint the non-client area. clip is currently unused. */ -void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) +void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint ) { - HDC hdc; - RECT rect; + HDC hdc; + RECT rect; + BOOL active; WND *wndPtr = WIN_FindWndPtr( hwnd ); - dprintf_nonclient(stddeb, "NC_DoNCPaint: %04x %d\n", hwnd, active ); if (!wndPtr || !(wndPtr->dwStyle & WS_VISIBLE)) return; /* Nothing to do */ + active = wndPtr->flags & WIN_NCACTIVATED; + + dprintf_nonclient(stddeb, "NC_DoNCPaint: %04x %d\n", hwnd, active ); + if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return; /* @@ -646,6 +651,13 @@ void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) DrawIcon(hdc, 0, 0, hIcon); } ReleaseDC(hwnd, hdc); + wndPtr->flags &= ~WIN_INTERNAL_PAINT; + if( wndPtr->hrgnUpdate ) + { + DeleteObject( wndPtr->hrgnUpdate ); + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); + wndPtr->hrgnUpdate = 0; + } return; } @@ -724,11 +736,9 @@ void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) * * Handle a WM_NCPAINT message. Called from DefWindowProc(). */ -LONG NC_HandleNCPaint( HWND hwnd ) +LONG NC_HandleNCPaint( HWND hwnd , HRGN clip) { - WND *wndPtr = WIN_FindWndPtr(hwnd); - - NC_DoNCPaint( hwnd, wndPtr->flags & WIN_NCACTIVATED, FALSE ); + NC_DoNCPaint( hwnd, clip, FALSE ); return 0; } @@ -745,7 +755,7 @@ LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam ) if (wParam != 0) wndPtr->flags |= WIN_NCACTIVATED; else wndPtr->flags &= ~WIN_NCACTIVATED; - NC_DoNCPaint( hwnd, (wParam != 0), FALSE ); + NC_DoNCPaint( hwnd, (HRGN)1, FALSE ); return TRUE; } @@ -1297,7 +1307,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt ) dprintf_nonclient(stddeb, "Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y ); - if (wndPtr->dwStyle & WS_CHILD) + if (wndPtr->dwStyle & WS_CHILD && wParam != SC_KEYMENU ) ScreenToClient( wndPtr->parent->hwndSelf, &pt ); switch (wParam & 0xfff0) @@ -1336,7 +1346,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt ) break; case SC_KEYMENU: - MENU_TrackKbdMenuBar( hwnd, wParam ); + MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x ); break; case SC_ARRANGE: diff --git a/windows/painting.c b/windows/painting.c index bd1554c913..e8ce1bbb71 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -17,6 +17,64 @@ /* Last CTLCOLOR id */ #define CTLCOLOR_MAX CTLCOLOR_STATIC +/*********************************************************************** + * WIN_UpdateNCArea + * + */ +void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) +{ + RECT rect = wnd->rectClient; + HRGN hClip = 1; + + dprintf_nonclient(stddeb,"NCUpdate: hwnd %04x, hrgnUpdate %04x\n", + wnd->hwndSelf, wnd->hrgnUpdate ); + + /* desktop windows doesn't have nonclient area */ + if(wnd == WIN_GetDesktop()) + { + wnd->flags &= ~WIN_NEEDS_NCPAINT; + return; + } + + if( wnd->hrgnUpdate > 1 ) + { + MapWindowPoints(wnd->parent->hwndSelf, 0, (POINT*)&rect, 2); + + hClip = CreateRectRgn( 0, 0, 0, 0 ); + if (!CombineRgn(hClip, wnd->hrgnUpdate, 0, RGN_COPY) ) + { + DeleteObject(hClip); + hClip = 1; + } + + if (bUpdate) + { + HRGN hrgn = CreateRectRgnIndirect(&rect); + if (hrgn && (CombineRgn(wnd->hrgnUpdate, wnd->hrgnUpdate, + hrgn, RGN_AND) == NULLREGION)) + { + DeleteObject(wnd->hrgnUpdate); + wnd->hrgnUpdate = 1; + } + DeleteObject( hrgn ); + } + } + + wnd->flags &= ~WIN_NEEDS_NCPAINT; + + if ((wnd->hwndSelf == GetActiveWindow()) && + !(wnd->flags & WIN_NCACTIVATED)) + { + wnd->flags |= WIN_NCACTIVATED; + if( hClip > 1) DeleteObject(hClip); + hClip = 1; + } + + if (hClip) SendMessage( wnd->hwndSelf, WM_NCPAINT, hClip, 0L ); + + if (hClip > 1) DeleteObject( hClip ); +} + /*********************************************************************** * BeginPaint (USER.39) @@ -27,26 +85,22 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; - hrgnUpdate = wndPtr->hrgnUpdate; /* Save update region */ - if (!hrgnUpdate) /* Create an empty region */ - if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0; + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; - if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) - QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); + if (wndPtr->flags & WIN_NEEDS_NCPAINT) WIN_UpdateNCArea( wndPtr, TRUE ); + + if (((hrgnUpdate = wndPtr->hrgnUpdate) != 0) || + (wndPtr->flags & WIN_INTERNAL_PAINT)) + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); wndPtr->hrgnUpdate = 0; - wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT); + wndPtr->flags &= ~WIN_INTERNAL_PAINT; HideCaret( hwnd ); - if (wndPtr->flags & WIN_NEEDS_NCPAINT) - { - wndPtr->flags &= ~WIN_NEEDS_NCPAINT; - SendMessage( hwnd, WM_NCPAINT, 0, 0 ); - } - lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE ); - DeleteObject( hrgnUpdate ); + if(hrgnUpdate > 1) DeleteObject( hrgnUpdate ); + if (!lps->hdc) { fprintf(stderr, "GetDCEx() failed in BeginPaint(), hwnd=%04x\n", hwnd); @@ -233,10 +287,8 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) else if (flags & RDW_ERASENOW) { if (wndPtr->flags & WIN_NEEDS_NCPAINT) - { - wndPtr->flags &= ~WIN_NEEDS_NCPAINT; - SendMessage( hwnd, WM_NCPAINT, 0, 0 ); - } + WIN_UpdateNCArea( wndPtr, FALSE); + if (wndPtr->flags & WIN_NEEDS_ERASEBKGND) { HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, diff --git a/windows/timer.c b/windows/timer.c index ca1a620ee3..9f8cc4a402 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -14,6 +14,7 @@ typedef struct tagTIMER { HWND hwnd; + HQUEUE hq; WORD msg; /* WM_TIMER or WM_SYSTIMER */ WORD id; WORD timeout; @@ -74,6 +75,58 @@ static void TIMER_RemoveTimer( TIMER * pTimer ) pTimer->next = NULL; } +/*********************************************************************** + * TIMER_SwitchQueue + */ +void TIMER_SwitchQueue(HQUEUE old, HQUEUE new) +{ + TIMER* pT = pNextTimer; + + while(pT) + { + if( pT->hq == old ) pT->hq = new; + pT = pT->next; + } + +} + +/*********************************************************************** + * TIMER_NukeTimers + * + * Trash all timers that are bound to the hwnd or hq + */ +void TIMER_NukeTimers(HWND hwnd, HQUEUE hq) +{ + HQUEUE hQToUpdate = ( hwnd ) ? GetTaskQueue( GetWindowTask( hwnd ) ) + : hq; + TIMER* pT = pNextTimer; + TIMER* pTnext; + + if( !pT ) return; + + while( (hwnd && pT->hwnd == hwnd) || + (hq && pT->hq == hq) ) + { + QUEUE_DecTimerCount( hQToUpdate ); + if( !(pT = pNextTimer = pNextTimer->next) ) + return; + } + + /* pT points to the "good" timer */ + + while( (pTnext = pT->next) ) + { + while( (hwnd && pTnext->hwnd == hwnd) || + (hq && pTnext->hq == hq) ) + { + QUEUE_DecTimerCount( hQToUpdate ); + if( !(pT->next = pTnext->next) ) + return; + } + + pT = pT->next; + } +} /*********************************************************************** * TIMER_RestartTimers @@ -165,6 +218,8 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, /* Add the timer */ pTimer->hwnd = hwnd; + pTimer->hq = (hwnd) ? GetTaskQueue( GetWindowTask( hwnd ) ) + : GetTaskQueue( 0 ); pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER; pTimer->id = id; pTimer->timeout = timeout; @@ -173,7 +228,7 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, dprintf_timer(stddeb, "Timer added: %p, %04x, %04x, %04x, %08lx\n", pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc); TIMER_InsertTimer( pTimer ); - QUEUE_IncTimerCount( GetTaskQueue(0) ); + QUEUE_IncTimerCount( pTimer->hq ); if (!id) return TRUE; else @@ -188,6 +243,7 @@ static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) { int i; TIMER * pTimer; + HQUEUE hq; /* Find the timer */ @@ -201,13 +257,15 @@ static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) /* Delete the timer */ + hq = pTimer->hq; + pTimer->hwnd = 0; pTimer->msg = 0; pTimer->id = 0; pTimer->timeout = 0; pTimer->proc = 0; TIMER_RemoveTimer( pTimer ); - QUEUE_DecTimerCount( GetTaskQueue(0) ); + QUEUE_DecTimerCount( hq ); return TRUE; } diff --git a/windows/win.c b/windows/win.c index 8511a73c5a..5c0b2ab4ed 100644 --- a/windows/win.c +++ b/windows/win.c @@ -217,30 +217,43 @@ BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ) * * Find a window that needs repaint. */ -HWND WIN_FindWinToRepaint( HWND hwnd ) +HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue ) { - WND * wndPtr; + HWND hwndRet; + WND *pWnd = pWndDesktop; - /* Note: the desktop window never gets WM_PAINT messages */ - wndPtr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child; - for ( ; wndPtr; wndPtr = wndPtr->next) + /* Note: the desktop window never gets WM_PAINT messages */ + pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child; + + for ( ; pWnd ; pWnd = pWnd->next ) { - dprintf_win( stddeb, "WIN_FindWinToRepaint: %04x, style %08lx\n", - wndPtr->hwndSelf, wndPtr->dwStyle ); - if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW)) + if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW)) + { + dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n", + pWnd->hwndSelf ); continue; - if ((wndPtr->dwStyle & WS_MINIMIZE) && (WIN_CLASS_INFO(wndPtr).hIcon)) - continue; - if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) - return wndPtr->hwndSelf; - if (wndPtr->child) - { - HWND child; - if ((child = WIN_FindWinToRepaint( wndPtr->child->hwndSelf ))) - return child; - } + } + if ((pWnd->hmemTaskQ == hQueue) && + (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break; + + if (pWnd->child ) + if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) ) + return hwndRet; } - return 0; + + if (!pWnd) return 0; + + hwndRet = pWnd->hwndSelf; + + /* look among siblings if we got a transparent window */ + while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) || + !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)))) + { + pWnd = pWnd->next; + } + if (pWnd) hwndRet = pWnd->hwndSelf; + dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet); + return hwndRet; } @@ -252,19 +265,35 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) */ void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue ) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); - - while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) + LPPOINT lppt = (LPPOINT)(void*)(&lValue); + WND *wndPtr = WIN_FindWndPtr( hwnd ); + BOOL bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST)); + + /* if lValue contains cursor coordinates they have to be + * mapped to the client area of parent window */ + + if (bMouse) MapWindowPoints(0, hwnd, lppt, 2); +#ifndef WINELIB32 + else lValue = MAKELONG( LOWORD(lValue), idChild ); +#endif + + while (wndPtr) { - if (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) break; + if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) || + !(wndPtr->dwStyle & WS_CHILD)) break; + + if (bMouse) + { + lppt->x += wndPtr->rectClient.left; + lppt->y += wndPtr->rectClient.top; + } + wndPtr = wndPtr->parent; #ifdef WINELIB32 SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, - MAKEWPARAM(event,idChild), - (LPARAM)lValue ); + MAKEWPARAM( event, idChild ), lValue ); #else - SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, - MAKELPARAM(LOWORD(lValue), idChild) ); + SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue); #endif } } @@ -1268,7 +1297,7 @@ static BOOL WIN_EnumChildWin( WND *wndPtr, FARPROC wndenumprc, LPARAM lParam ) pWndChild = wndPtr->child; /* ..side effects after wndenumprc */ if (!CallEnumWindowsProc( wndenumprc, wndPtr->hwndSelf, lParam )) return 0; - if (IsWindow(pWndChild->hwndSelf)) /*to prevent too early termination*/ + if (pWndChild && IsWindow(pWndChild->hwndSelf)) if (!WIN_EnumChildWin(pWndChild, wndenumprc, lParam)) return 0; wndPtr = pWndNext; } diff --git a/windows/winpos.c b/windows/winpos.c index 29f3d704f3..524f285ed9 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -6,7 +6,7 @@ */ #include "sysmetrics.h" -#include "selectors.h" +#include "module.h" #include "user.h" #include "win.h" #include "event.h" @@ -238,7 +238,7 @@ INT WINPOS_WindowFromPoint( POINT pt, WND **ppWnd ) /* Restart the search from the next sibling */ wndPtr = (*ppWnd)->next; - *ppWnd = wndPtr->parent; + *ppWnd = (*ppWnd)->parent; } } @@ -259,22 +259,29 @@ HWND WindowFromPoint( POINT pt ) */ HWND ChildWindowFromPoint( HWND hwndParent, POINT pt ) { + /* pt is in the client coordinates */ + + WND* wnd = WIN_FindWndPtr(hwndParent); RECT rect; - HWND hwnd; - - GetWindowRect( hwndParent, &rect ); + + if( !wnd ) return 0; + + /* get client rect fast */ + rect.top = rect.left = 0; + rect.right = wnd->rectClient.right - wnd->rectClient.left; + rect.bottom = wnd->rectClient.bottom - wnd->rectClient.top; + if (!PtInRect( &rect, pt )) return 0; - hwnd = GetTopWindow( hwndParent ); - while (hwnd) + + wnd = wnd->child; + while ( wnd ) { - GetWindowRect( hwnd, &rect ); - if (PtInRect( &rect, pt )) return hwnd; - hwnd = GetWindow( hwnd, GW_HWNDNEXT ); + if (PtInRect( &wnd->rectWindow, pt )) return wnd->hwndSelf; + wnd = wnd->next; } return hwndParent; } - /******************************************************************* * MapWindowPoints (USER.258) */ @@ -652,10 +659,15 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) WND *wndPtr = WIN_FindWndPtr(hWnd); WND *wndTemp = WIN_FindWndPtr(hwndActive); CBTACTIVATESTRUCT cbtStruct = { fMouse , hwndActive }; - FARPROC enumCallback = (FARPROC)GetWndProcEntry16("ActivateAppProc"); + FARPROC enumCallback = MODULE_GetWndProcEntry16("ActivateAppProc"); ACTIVATESTRUCT actStruct; WORD wIconized=0,wRet= 0; - HANDLE hActiveQ = 0; + + /* FIXME: When proper support for cooperative multitasking is in place + * hActiveQ will be global + */ + + HANDLE hActiveQ = 0; /* paranoid checks */ if( !hWnd || hWnd == GetDesktopWindow() || hWnd == hwndActive ) @@ -805,16 +817,24 @@ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) if( !wndPtr ) return FALSE; - /* minors are not allowed */ + /* child windows get WM_CHILDACTIVATE message */ if( (wndPtr->dwStyle & WS_CHILD) && !( wndPtr->dwStyle & WS_POPUP)) return SendMessage(hWnd, WM_CHILDACTIVATE, 0, 0L); + /* owned popups imply owner activation */ + if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner ) + { + wndPtr = wndPtr->owner; + if( !wndPtr ) return FALSE; + hWnd = wndPtr->hwndSelf; + } + if( hWnd == hwndActive ) return FALSE; if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) ) return FALSE; - /* switch desktop queue to current active here */ + /* switch desktop queue to current active */ if( wndPtr->parent == WIN_GetDesktop()) WIN_GetDesktop()->hmemTaskQ = wndPtr->hmemTaskQ; @@ -947,6 +967,79 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter ) } } +/*********************************************************************** + * WINPOS_ReorderOwnedPopups + * + * fix Z order taking into account owned popups - + * basically we need to maintain them above owner window + */ +HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter, WND* wndPtr, WORD flags) +{ + WND* w = WIN_GetDesktop(); + + w = w->child; + + /* if we are dealing with owned popup... + */ + if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner && hwndInsertAfter != HWND_TOP ) + { + BOOL bFound = FALSE; + HWND hwndLocalPrev = HWND_TOP; + HWND hwndNewAfter = 0; + + while( w ) + { + if( !bFound && hwndInsertAfter == hwndLocalPrev ) + hwndInsertAfter = HWND_TOP; + + if( w->dwStyle & WS_POPUP && w->owner == wndPtr->owner ) + { + bFound = TRUE; + + if( hwndInsertAfter == HWND_TOP ) + { + hwndInsertAfter = hwndLocalPrev; + break; + } + hwndNewAfter = hwndLocalPrev; + } + + if( w == wndPtr->owner ) + { + /* basically HWND_BOTTOM */ + hwndInsertAfter = hwndLocalPrev; + + if( bFound ) + hwndInsertAfter = hwndNewAfter; + break; + } + + if( w != wndPtr ) + hwndLocalPrev = w->hwndSelf; + + w = w->next; + } + } + else + /* or overlapped top-level window... + */ + if( !(wndPtr->dwStyle & WS_CHILD) ) + while( w ) + { + if( w == wndPtr ) break; + + if( w->dwStyle & WS_POPUP && w->owner == wndPtr ) + { + SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | + SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE); + hwndInsertAfter = w->hwndSelf; + } + w = w->next; + } + + return hwndInsertAfter; +} + /*********************************************************************** * WINPOS_SetXWindowPos @@ -1079,6 +1172,12 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, if (!(winpos.flags & SWP_NOZORDER)) { + /* reorder owned popups if hwnd is top-level window + */ + if( wndPtr->parent == WIN_GetDesktop() ) + hwndInsertAfter = WINPOS_ReorderOwnedPopups( hwndInsertAfter, + wndPtr, flags ); + if (wndPtr->window) { WIN_UnlinkWindow( winpos.hwnd ); @@ -1098,9 +1197,14 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, if (wndPtr->window) { + HWND bogusInsertAfter = winpos.hwndInsertAfter; + + winpos.hwndInsertAfter = hwndInsertAfter; WINPOS_SetXWindowPos( &winpos ); + wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; + winpos.hwndInsertAfter = bogusInsertAfter; } else { diff --git a/wine.man b/wine.man index 2f3f6c5f15..c08f5647c3 100644 --- a/wine.man +++ b/wine.man @@ -104,7 +104,7 @@ Start as an icon .I -language xx Set the language to .I xx -(one of En, Es, De, No, Fr, Fi, Da, Cz, Eo) +(one of En, Es, De, No, Fr, Fi, Da, Cz, Eo, It) .TP .I -managed Create each top-level window as a properly managed X window