Release 960331
Sun Mar 31 13:54:46 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [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 <kreider@natlab.research.philips.com>
* [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 <alex@phm30.pharm.sunysb.edu>
* [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 <msmeissn@cip.informatik.uni-erlangen.de>
* [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 <dorssel@rulhm1.leidenuniv.nl>
* [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 <krynos@qbc.clic.net>
* [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 <tst@dcs.ed.ac.uk>
* [resources/sysres_it.rc]
Added support for Italian [It] language.
diff --git a/ANNOUNCE b/ANNOUNCE
index 6485e58..64fa517 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 @@
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 687c402..88685439 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,124 @@
----------------------------------------------------------------------
+Sun Mar 31 13:54:46 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
+
+ * [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 <kreider@natlab.research.philips.com>
+
+ * [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 <alex@phm30.pharm.sunysb.edu>
+
+ * [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 <msmeissn@cip.informatik.uni-erlangen.de>
+
+ * [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 <dorssel@rulhm1.leidenuniv.nl>
+
+ * [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 <krynos@qbc.clic.net>
+
+ * [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 <tst@dcs.ed.ac.uk>
+
+ * [resources/sysres_it.rc]
+ Added support for Italian [It] language.
+
+----------------------------------------------------------------------
Sun Mar 24 13:13:11 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [include/win.h] [windows/*.c]
diff --git a/Make.rules.in b/Make.rules.in
index 3ae1d05..b07b131 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -16,7 +16,7 @@
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 f637b0f..8ac780f 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -235,21 +235,17 @@
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 @@
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 4537c02..6b1154c 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2798,12 +2798,7 @@
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 6bba90f..21f66b4 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 @@
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 @@
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 @@
}
}
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 @@
}
return 0;
-}
+ }
/***********************************************************************
* LBKeyDown
@@ -1281,7 +1284,7 @@
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 @@
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 0457c11..33e58b3 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 @@
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 @@
*
* 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 @@
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 4ae39e3..e541835 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 @@
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 f896da8..311fcab 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -2,12 +2,17 @@
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 @@
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 @@
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 b5de7d9..28916c4 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 @@
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 @@
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 5967fef..668d7a9 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 7681ce3..8ca5480 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 3f2e25c..c579065 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 c7cffb8..398c68c 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 d585ef5..0a03761 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 a01f1b1..08d7d6a 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 299f833..dae9cc1 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 7d874ed..c2cabe6 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 @@
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 3388430..f205374 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 714bd3c..5820363 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 9f2e38d..3e6b2c9 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 14171d4..cb28204 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 0c04a8d..fe8599f 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 c3caa82..f7c8ad2 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 d2414bd..39808a8 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 e8f34bf..1364f5a 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 9e70445..57b136a 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 1d3868a..e2822cb 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 f9c6dd2..cf93117 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 03ef5ca..9376d69 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 ca3f1bd..a79115d 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 b0f3d9b..c3960ba 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 @@
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 @@
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 @@
/***********************************************************************
- * 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 @@
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 4ec1104..418f1cc 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 *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_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 && hint<dll->size)
- 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 && hint<dll->size &&
+ 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;i<dll->size;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 && hint<dll->size && !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 @@
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 @@
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 @@
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 8f01e02..f7b2bea 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 @@
# 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 1e191e2..1e0a54b 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 2191fdd..23b656f 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 08efdc3..2c03b1e 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 738de00..69c8309 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 de7816e..975364c 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 1c590d4..9085053 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 fcc0b1b..721fde0 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 9934c77..13e7ab7 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 @@
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 71759fa..7cee198 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 e564fa5..62274e8 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 6bb7b0b..d40dafa 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 813f364..52975071 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 d3ac315..12e16f6 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 634c3f4..d4531ad 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 26daa04..c6d93e3 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 @@
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 e372a1e..5f77564 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 00b5980..2e5bcbc 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(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 1b0febc..2a078d3 100644
--- a/include/kernel32.h
+++ b/include/kernel32.h
@@ -92,20 +92,6 @@
#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 41f2047..32c4ff7 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -12,7 +12,7 @@
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 af6b061..0ee35f6 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 c19f764..bc23e1c 100644
--- a/include/module.h
+++ b/include/module.h
@@ -105,10 +105,12 @@
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 e8c460c..096050b 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -26,38 +26,38 @@
*/
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 @@
*/
#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 d2ca8ab..c890201 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 1513a3a..c1b6f0e 100644
--- a/include/options.h
+++ b/include/options.h
@@ -18,7 +18,8 @@
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 944d2ff..799392a 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -25,13 +25,11 @@
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 d06f13d..e826d8d 100644
--- a/include/selectors.h
+++ b/include/selectors.h
@@ -17,8 +17,4 @@
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 481f149..d28caba 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 @@
#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 a50bb01..eaadefd 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 43b3fa6..a4ecf1b 100644
--- a/include/win.h
+++ b/include/win.h
@@ -82,7 +82,7 @@
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 fa91818..b823ad3 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1088,6 +1088,20 @@
#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 @@
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 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 67e8d71..cdca7ea 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -7,6 +7,7 @@
*/
#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 @@
#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 0000000..01c60a0
--- /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 52e0548..8f53926 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -49,6 +49,7 @@
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 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 b06c6a6..0c3f8c1 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -169,11 +169,11 @@
}
/***********************************************************************
- * 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 @@
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 0aca285..0c49037 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -11,11 +11,13 @@
#include <string.h>
#include <errno.h>
#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 @@
/* 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 7cece76..fce734c 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -48,20 +48,18 @@
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 @@
}
}
+ /* 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 @@
*
* 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 @@
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 @@
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",
@@ -794,6 +794,40 @@
/***********************************************************************
+ * 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
*/
LPSTR MODULE_GetModuleName( HMODULE hModule )
@@ -1103,10 +1137,6 @@
/* 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 @@
}
-/***********************************************************************
- * 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 1b8c0a6..8ae9004 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -510,11 +510,11 @@
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 e95ade2..ced45d0 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 @@
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 @@
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 dee9027..0de3993 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 @@
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 @@
*/
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 @@
{
#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 @@
{
#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 @@
{
#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 @@
*/
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 @@
*/
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 @@
*/
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 @@
(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 995741b..8ebc0b6 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -7,6 +7,9 @@
#include <time.h>
#include <setjmp.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__)
#include <sys/syscall.h>
#include <sys/param.h>
@@ -43,7 +46,33 @@
#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 @@
#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 @@
}
}
+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 @@
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 @@
#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 1b6c557..0fc4a67 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 @@
*/
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 @@
FILE_CloseAllFiles( pTask->hPDB );
+ /* Nuke timers */
+
+ TIMER_NukeTimers( 0, pTask->hQueue );
+
/* Free the message queue */
QUEUE_DeleteMsgQueue( pTask->hQueue );
@@ -999,8 +1005,12 @@
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 @@
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 @@
#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 4196c1c..1266b05 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -21,6 +21,7 @@
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 3d242f7..66beced 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 8058a7c..8f8c31b 100644
--- a/misc/keyboard.c
+++ b/misc/keyboard.c
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include "windows.h"
#include "keyboard.h"
#include "stddebug.h"
@@ -19,14 +20,27 @@
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 34f3b95..caa253f 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -57,6 +57,7 @@
"Da", /* LANG_Da */
"Cz", /* LANG_Cz */
"Eo", /* LANG_Eo */
+ "It", /* LANG_It */
NULL
};
@@ -139,7 +140,7 @@
" -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 @@
*/
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;i<N_BUILTINS;i++)
- if (!lstrncmpi(options+1,dll_builtin_table[i].name,l-1))
- {
- dll_builtin_table[i].used = (*options=='+');
- break;
- }
- if (i==N_BUILTINS)
- return FALSE;
- options+=l;
- }
- while((*options==',')&&(*(++options)));
- if (*options)
- return FALSE;
- else
- return TRUE;
+ int i, l;
+ BUILTIN_DLL *dll;
+
+ if (strlen(options)<3) return FALSE;
+ do
+ {
+ if ((*options!='+') && (*options!='-')) return FALSE;
+ if (strchr(options,',')) l=strchr(options,',')-options;
+ else l=strlen(options);
+ for (dll = dll_builtin_table; dll->name; 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 @@
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;i<N_BUILTINS;i++)
- fprintf(stderr,"%-9s%c",dll_builtin_table[i].name,
- (((i+2)%8==0)?'\n':' '));
+ for (dll = dll_builtin_table; dll->name; 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 51cd354..fc93301 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -32,6 +32,7 @@
case LANG_Da:
case LANG_Cz:
case LANG_Eo:
+ case LANG_It:
default:
return 0; /* Neutral language */
}
@@ -523,6 +524,130 @@
/* 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 0000000..1cff39f
--- /dev/null
+++ b/misc/registry.c
@@ -0,0 +1,1885 @@
+/*
+ * Registry Functions
+ *
+ * Copyright 1996 Marcus Meissner
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#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<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))
+
+#define strdupA2W(x) STRING32_DupAnsiToUni(x)
+#define strdupW2A(x) STRING32_DupUniToAnsi(x)
+#define strdupW(x) STRING32_strdupW(x)
+#define strcmpW(a,b) STRING32_lstrcmpW(a,b)
+#define strcmpniW(a,b) STRING32_lstrcmpniW(a,b)
+#define strchrW(a,c) STRING32_lstrchrW(a,c)
+#define strlenW(a) STRING32_UniLen(a)
+#define strcpyWA(a,b) STRING32_UniToAnsi(a,b)
+
+static struct openhandle {
+ LPKEYSTRUCT lpkey;
+ HKEY hkey;
+ REGSAM accessmask;
+} *openhandles=NULL;
+static int nrofopenhandles=0;
+static int currenthandle=1;
+
+static void
+add_handle(HKEY hkey,LPKEYSTRUCT lpkey,REGSAM accessmask) {
+ int i;
+
+ for (i=0;i<nrofopenhandles;i++) {
+ if (openhandles[i].lpkey==lpkey) {
+ dprintf_reg(stddeb,"add_handle:Tried to add %p twice!\n",lpkey);
+ }
+ if (openhandles[i].hkey==hkey) {
+ dprintf_reg(stddeb,"add_handle:Tried to add %lx twice!\n",(LONG)hkey);
+ }
+ }
+ openhandles=xrealloc( openhandles,
+ sizeof(struct openhandle)*(nrofopenhandles+1)
+ );
+ openhandles[i].lpkey = lpkey;
+ openhandles[i].hkey = hkey;
+ openhandles[i].accessmask= accessmask;
+ nrofopenhandles++;
+}
+
+static LPKEYSTRUCT
+get_handle(hkey) {
+ int i;
+
+ for (i=0;i<nrofopenhandles;i++)
+ if (openhandles[i].hkey==hkey)
+ return openhandles[i].lpkey;
+ dprintf_reg(stddeb,"get_handle:Didn't find handle %lx?\n",(LONG)hkey);
+ return NULL;
+}
+
+static void
+remove_handle(HKEY hkey) {
+ int i;
+
+ for (i=0;i<nrofopenhandles;i++)
+ if (openhandles[i].hkey==hkey)
+ break;
+ if (i==nrofopenhandles) {
+ dprintf_reg(stddeb,"remove_handle:Didn't find handle %lx?\n",hkey);
+ return;
+ }
+ memcpy( openhandles+i,
+ openhandles+i+1,
+ sizeof(struct openhandle)*(nrofopenhandles-i-1)
+ );
+ openhandles=xrealloc(openhandles,sizeof(struct openhandle)*(nrofopenhandles-1));
+ nrofopenhandles--;
+ return;
+}
+
+
+/* debug function, converts a unicode into a static memory area
+ * (sub for using two static strings, in case we need them in a single call)
+ */
+LPSTR
+W2C(LPCWSTR x,int sub) {
+ static LPSTR unicodedebug[2]={NULL,NULL};
+ if (x==NULL)
+ return "<NULL>";
+ if (sub!=0 && sub!=1)
+ return "<W2C:bad sub>";
+ 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;i<len;i++)
+ if (ws[i-1]==0)
+ (*wpv)[j++]=ws+i;
+ (*wpv)[j]=NULL;
+}
+#define FREE_KEY_PATH free(wps[0]);free(wps);
+
+/**
+ * Shell initialisation, allocates keys.
+ * FIXME:should set default values too
+ */
+void
+SHELL_Init() {
+#define ADD_ROOT_KEY(xx) \
+ xx = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));\
+ memset(xx,'\0',sizeof(KEYSTRUCT));\
+ xx->keyname= strdupA2W("<should_not_appear_anywhere>");
+
+ 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;i<lpxkey->nrofvalues;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;i<lpxkey->nrofvalues;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 (i<wpc) {
+ lpxkey=lpNextKey->nextsub;
+ 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 (i<wpc) {
+ lpxkey=lpNextKey->nextsub;
+ 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 (i<wpc) {
+ lplpPrevKey = &(lpNextKey->nextsub);
+ 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;i<lpkey->nrofvalues;i++)
+ if (lpkey->values[i].name==NULL)
+ break;
+ } else {
+ for (i=0;i<lpkey->nrofvalues;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 (*lpcbData<lpkey->values[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;i<lpkey->nrofvalues;i++)
+ if (lpkey->values[i].name==NULL)
+ break;
+ } else {
+ for (i=0;i<lpkey->nrofvalues;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<<dwType) & UNICONVMASK) {
+ buf=(LPBYTE)strdupA2W(lpbData);
+ cbData=2*strlen(lpbData)+2;
+ } else
+ buf=lpbData;
+ if (lpszValueName)
+ lpszValueNameW = strdupA2W(lpszValueName);
+ else
+ lpszValueNameW = NULL;
+ ret=RegSetValueExW(hkey,lpszValueNameW,dwReserved,dwType,buf,cbData);
+ if (lpszValueNameW)
+ free(lpszValueNameW);
+ if (buf!=lpbData)
+ free(buf);
+ return ret;
+}
+
+/* RegSetValueEx [KERNEL.226] */
+WINAPI DWORD
+RegSetValueEx(
+ HKEY hkey,
+ LPSTR lpszValueName,
+ DWORD dwReserved,
+ DWORD dwType,
+ LPBYTE lpbData,
+ DWORD cbData
+) {
+ dprintf_reg(stddeb,"RegSetValueEx(%lx,%s,%ld,%ld,%p,%ld)\n->",
+ 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->nrofvalues<iValue)
+ return ERROR_NO_MORE_ITEMS;
+ val = lpkey->values+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 (i<wpc-1) {
+ lpxkey=lpNextKey->nextsub;
+ 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;i<lpkey->nrofvalues;i++)
+ if (!strcmpW(lpkey->values[i].name,lpszValue))
+ break;
+ } else {
+ for (i=0;i<lpkey->nrofvalues;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;i<lpxkey->nrofvalues;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 12aea21..c209531 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -8,10 +8,8 @@
#include <ctype.h>
#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;i<tabs;i++) fprintf(f,"\t");
- /* implement different dwTypes ... */
- if (lpKey->lpValue)
- 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 (i<tabsexp) return;
-
- if (i>tabsexp) {
- 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 (i<tabsexp) return;
- if (buf[0]=='\0') break; /* marks end of file */
- /* we have a buf now. even when returning from _LoadLevel */
- hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
- lpNewKey = lpKey->lpNextKey=(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 @@
{
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 @@
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 0765edf..a228f71 100644
--- a/misc/xmalloc.c
+++ b/misc/xmalloc.c
@@ -35,7 +35,7 @@
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 92b0cdc..d3d5fa9 100644
--- a/miscemu/dosmem.c
+++ b/miscemu/dosmem.c
@@ -132,18 +132,13 @@
/***********************************************************************
- * 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_FillBiosSegment(void)
{
+ extern void SIGNAL_StartBIOSTimer(void);
+
pBiosData = (BIOSDATA *)GlobalLock( DOSMEM_BiosSeg );
/* Clear all unused values */
@@ -179,8 +176,6 @@
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 1e54951..14ac461 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -30,7 +30,6 @@
{
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 c9e7f22..f0e21fe 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 @@
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 63204cf..36bbe20 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -94,8 +94,13 @@
{ 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 2929a01..6ad5d4e 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -522,10 +522,15 @@
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 @@
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 @@
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 c5a2349..7688fe9 100644
--- a/programs/progman/ChangeLog
+++ b/programs/progman/ChangeLog
@@ -1,3 +1,16 @@
+Sun Mar 24 12:28:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+
+ * [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 <uschmid@mail.hh.provi.de>
+
+ * [winexec.c] (deleted)
+ Moved code to loader/modules.c
+
Fri Mar 15 20:56:31 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
* [main.c]
diff --git a/programs/progman/De.rc b/programs/progman/De.rc
index 9284517..5420f90 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 97fb14b..c8fe792 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 241c566..ee8a900 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -18,8 +18,7 @@
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 b145c28..8cd4c34 100644
--- a/programs/progman/README
+++ b/programs/progman/README
@@ -12,5 +12,3 @@
`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 de3d369..0000000
--- a/programs/progman/Strings_De.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <windows.h>
-#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 da3f19d..0000000
--- a/programs/progman/Strings_En.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <windows.h>
-#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 44d7991..e08b09e 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 @@
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 @@
/* 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 @@
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 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 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 c19ca83..f35d425 100644
--- a/programs/progman/dialog.c
+++ b/programs/progman/dialog.c
@@ -8,7 +8,8 @@
#include <commdlg.h>
#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 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
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 0646f8f..a133b55 100644
--- a/programs/progman/group.c
+++ b/programs/progman/group.c
@@ -109,7 +109,7 @@
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 50e99ec..1e292a0 100644
--- a/programs/progman/grpfile.c
+++ b/programs/progman/grpfile.c
@@ -63,14 +63,15 @@
/* 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 @@
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 @@
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 @@
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 @@
}
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 4d3cd13..e9906ff 100644
--- a/programs/progman/main.c
+++ b/programs/progman/main.c
@@ -34,6 +34,13 @@
{
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 @@
#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 @@
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 @@
{
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 @@
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 @@
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 @@
#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;
}
}
@@ -464,6 +453,38 @@
/**********************************************************************/
/***********************************************************************
*
+ * 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 @@
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 875598b..c2dea1f 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 @@
HMENU hFileMenu;
HMENU hOptionMenu;
HMENU hWindowsMenu;
+ HMENU hLanguageMenu;
LPCSTR lpszIniFile;
LPCSTR lpszIcoFile;
BOOL bAutoArrange;
@@ -120,20 +123,15 @@
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 @@
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 @@
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_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 */
-#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);
+#define STRINGID(id) id
+
#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 @@
#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 d9e4b4a..b2ecdfb 100644
--- a/programs/progman/program.c
+++ b/programs/progman/program.c
@@ -159,7 +159,7 @@
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 be7ae15..f33941b 100644
--- a/programs/progman/string.c
+++ b/programs/progman/string.c
@@ -20,7 +20,7 @@
/* 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_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 @@
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);
- /* have to be last because of
- * the possible recursion */
- Globals.lpszLanguage = lang;
+ /* Destroy old menu */
+ if (Globals.hMainMenu) DestroyMenu(Globals.hMainMenu);
+ Globals.hMainMenu = hMainMenu;
+
#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 7cb7871..dc53de0 100644
--- a/resources/Makefile.in
+++ b/resources/Makefile.in
@@ -2,7 +2,7 @@
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 28e4df9..db771cc 100644
--- a/resources/TODO
+++ b/resources/TODO
@@ -15,3 +15,6 @@
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 ae1cbd0..832d026 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 @@
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 723ea2d..3a241bd 100644
--- a/resources/sysres_Fr.rc
+++ b/resources/sysres_Fr.rc
@@ -165,37 +165,38 @@
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 0000000..15a0136
--- /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 141a066..88887c1 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 @@
--------------------
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 938f99f..04f7a68 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <ctype.h>
#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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
/* 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 @@
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 <sys/types.h>\n");
- printf( "#include <stdarg.h>\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;argno<argc;argno++)
- {
- 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( ") __attribute((stdcall));\n" );
- }
-#endif
- printf( "void %s_%d(", UpperDLLName, i);
- for(argno=0;argno<argc;argno++)
- {
- if(odp->type == 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;argno<argc;argno++)
- if(fdp->arg_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;argno<argc;argno++)
- if(fdp->arg_types[argno]!='.') printf( ",%c", 'a'+argno);
- printf( ");\n\t%s(", fdp->internal_name );
- for(argno=0;argno<argc;argno++)
- {
- if (fdp->arg_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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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);
}
}
@@ -1046,6 +959,36 @@
/*******************************************************************
+ * 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
*
* Build the function used to switch to the original 32-bit stack
@@ -1718,11 +1661,102 @@
}
+/*******************************************************************
+ * 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 @@
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 @@
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 e60c784..c6fc137 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 @@
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 45188ce..e789cf8 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 fa923b2..6de4c20 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 @@
*/
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 e09042a..66e243e 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 @@
*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 @@
}
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 42a4582..b9a9db5 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -9,6 +9,7 @@
#include <unistd.h>
#include <stdio.h>
+#include <stdarg.h>
#include "windows.h"
#include "winerror.h"
#include "relay32.h"
@@ -527,3 +528,8 @@
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 df87319..5716094 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 @@
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 @@
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 b753d86..294fac5 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 @@
{
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 @@
{
KillSystemTimer((HWND)0, Caret.timerid);
Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout,
- (FARPROC)GetWndProcEntry16("CARET_Callback"));
+ MODULE_GetWndProcEntry16("CARET_Callback"));
}
}
@@ -120,27 +118,6 @@
/*****************************************************************
- * 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)
*/
BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height)
@@ -176,9 +153,6 @@
Caret.y = 0;
Caret.timeout = GetProfileInt( "windows", "CursorBlinkRate", 750 );
-
- CARET_Initialize();
-
return TRUE;
}
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 530c5e5..d081f22 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 @@
case WM_PAINTICON:
case WM_NCPAINT:
- return NC_HandleNCPaint( hwnd );
+ return NC_HandleNCPaint( hwnd, (HRGN)wParam );
case WM_NCHITTEST:
{
@@ -246,7 +250,7 @@
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 @@
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 */
- /* Send to WS_OVERLAPPED parent. TODO: Handle MDI */
+ if( ( wParam == VK_MENU && iMenuSysKey )
+ || ( wParam == VK_F10 && iF10Key ) )
+
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 793cffb..a3fc33d 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -655,6 +655,9 @@
#endif
}
break;
+
+ default:
+ TranslateMessage( msg );
}
break; /* case WM_KEYDOWN */
diff --git a/windows/event.c b/windows/event.c
index eba633f..19fa10a 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -54,8 +54,12 @@
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 @@
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 @@
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 @@
}
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 0c1ae3e..bdf8030 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -15,8 +15,10 @@
/**********************************************************************
* 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 @@
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 f3f8000..a22d1de 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -174,7 +174,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 415f39c..6a88fc6 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 @@
{
/* 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 @@
{
int pos, mask;
MESSAGEQUEUE *msgQueue;
+ HQUEUE hQueue;
LONG nextExp; /* Next timer expiration time */
#ifdef CONFIG_IPC
@@ -403,7 +410,8 @@
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 @@
/* 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 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 @@
/***********************************************************************
* 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 33ebe2c..c8215fd 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 @@
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 70b8125..c94ca9c 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 @@
/***********************************************************************
* 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 @@
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 @@
*
* 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 @@
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 @@
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 @@
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 bd1554c..e8ce1bb 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 @@
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 @@
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 ca1a620..9f8cc4a 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 @@
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 @@
/* 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 @@
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 @@
{
int i;
TIMER * pTimer;
+ HQUEUE hq;
/* Find the timer */
@@ -201,13 +257,15 @@
/* 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 8511a73..5c0b2ab 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -217,30 +217,43 @@
*
* 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 @@
*/
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 @@
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 29f3d70..524f285 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 @@
/* Restart the search from the next sibling */
wndPtr = (*ppWnd)->next;
- *ppWnd = wndPtr->parent;
+ *ppWnd = (*ppWnd)->parent;
}
}
@@ -259,22 +259,29 @@
*/
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 @@
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 @@
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 @@
}
}
+/***********************************************************************
+ * 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 @@
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 @@
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 2f3f6c5..c08f564 100644
--- a/wine.man
+++ b/wine.man
@@ -104,7 +104,7 @@
.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