Re: WINE server messages

2001-05-31 Thread David Howells

> Maintaining a section list in the server is certainly something we
> could do, but I don't really see why you want to get rid of the
> modules list. What would you gain by doing that?>

NtMapViewOfSection/NtUnmapViewOfSection.

Admittedly, these would be hard to implement fully in the current Wine
userspace server I think (they can map a section handle into _another_
process's VM space). However, it's something I can do in kernel space
reasonably easily.

And then there's NtQueryVirtualMemory. This can return a handle to the backing
section (assuming I'm recalling this correctly) in some other process.

Actually, I see that you do maintain a view list in the client as well as the
module list and section lists in the server. What I was thinking of was just
consolidating the three into a single view list and a single section list in
the server.

In effect, Wine'd still have the module list, it's just that there'd be
non-modules in the list too.

This would mean that the debugger could query from the server what Windows VM
mappings should be expected.

And, of course, it'd make writing the kernel module slightly easier:-)

David





WINE server messages

2001-05-30 Thread David Howells

Hello Alexandre,

I'm having a little trouble deciding exactly how to emulate the "module
registration" functionality in my kernel module. It occurs to me that this
might be easier to accomplish with a change to the current wine server message
set. My idea is:

 * Have the server only deal with NT Section objects and views of Sections.

 * Have no separate module table attached to a process.

 * Implement NtQuerySectionInformation/NtSetSectionInformation calls (or
   whatever they're called) as wineserver messages.

 * Add an extra Wine-specific information class for the purpose of recording
   the extra module information.

 * The wineserver process structure can then be changed so that rather than
   keeping a separate list of process_dlls, they can just keep a list of
   section views, some of which will be images/modules.

David





Re: STATUS_* codes

2001-05-01 Thread David Howells


STATUS_INVALID_EXECUTABLE_IMAGE

should have read:

STATUS_INVALID_IMAGE_FORMAT

and I'm told that the value is 0xC07B.

Cheers,
David





STATUS_* codes

2001-04-30 Thread David Howells


Can someone pin numbers on the following codes:

STATUS_FILE_IS_A_DIRECTORY
STATUS_INVALID_EXECUTABLE_IMAGE

At least I think that's what they're called (unfortunately, my book's at home
where I can't check it).

They're listed in my NT native API book (though that's no guarantee that they
exist), but not in the Wine header files, and I don't have a copy of the DDK
installed on top of MSDEV.

David





Re: Speeding up wineserver syncronization objects with shared memory

2001-04-03 Thread David Howells


Okay, I've thought about how to make the wine kernel module easier to use for
Wine, and I've started adding another API to it - one that interprets Wine
server messages. When I designed the module initially, I decided to make it
possible to add as many API's as I liked, so in theory it's not too difficult.

I'm currently performing a major rearrangement of the files that comprise the
module:

* Splitting the current win32 API bits out of the same files that
  contain the actual object class implementations.

* Putting the core and the API's in separate subdirectories.

* Abstracting name support, so that the internal API takes an "object
  name" which the user API is responsible for extracting from
  userspace and converting from WCS/MBS as necessary.

* Fixing introduced bugs.

This does not mean that I'm getting rid of the Win32 API I've already got! It
will just be optional.

Calling the new API will be by means of either:

union generic_request msg;
syscall(__NR_win32,WINESERVER_WINE_SERVER_MESSAGE,&msg);

Or:

union generic_request msg;
int fd = open("/proc/wineserver");
struct WineserverIoctl wioc = { WINESERVER_WINE_SERVER_MESSAGE, &msg };
ioctl(fd,WINESERVER_IOCTL,&wioc);

David





Re: Speeding up wineserver syncronization objects with shared memory

2001-03-08 Thread David Howells

> OK, this has apparently changed in kernel 2.4; in kernel 2.2 block
> size alignment is enough. That's unfortunate, but I guess it was
> necessary to support large files or memory sizes. Then yes, in 2.4
> your patch will be more useful.

As far as I know, it's the case on most Unices, though it maybe not be so on
older versions of Linux. It's part of the definition of mmap() too, I think.

David





Re: Speeding up wineserver syncronization objects with shared memory

2001-03-08 Thread David Howells

> I'll have to write a small program to collect some statistics:-)

Okay, I did a quick and dirty program to do that. It looked through the
following products that I've got installed:

Win2000 sp1
MSDEV 98
MS Office 2000

Using the following command:

find  /fs/win2000/WINNT \
  "/fs/win2000/Program Files/Microsoft Visual Studio" \
  "/fs/win2000/Program Files/Microsoft Office" -type f |
./scandll

And came up with the following statistics:

files accessed  : 3985
valid PE images : 1752
- libraries : 1280
  - badly VM aligned: 20
  - standard image base : 42
  - specific image base : 1218
  - file align by sector: 976
  - file align by page  : 284
- executables   : 472
  - badly VM aligned: 133
  - standard image base : 70
  - specific image base : 269
  - file align by sector: 287
  - file align by page  : 52

I've attached the program I used.

As you can see, most DLLs actually have their image base set manually to avoid
conflicts. Also a lot of EXEs have it set too... presumably so that they can
also be used as DLLs.

However! the majority of DLLs and EXEs are sector-aligned (512) in the files,
not page-aligned (4096).

David



/* scandll.c: scan DLLs and EXEs
 *
 * Copyright (c) 2001   David Howells ([EMAIL PROTECTED]).
 */
#include 
#include 
#include 
#include 
#include 
#include 

typedef __u8BOOL, BYTE;
typedef __u16   WORD;
typedef __u32   DWORD, UINT;

#define PAGE_SIZE 4096

#define _H_229A4E44_C7CC_11D4_8F92_C0005742 /* skip section.h */
#include "pefile.h"

IMAGE_SECTION_HEADER sechdr;
IMAGE_DOS_HEADER imghdr;
IMAGE_NT_HEADERS nthdr;

int files;
int valid_image;
int dlls;
int exes;
int bad_vm_align[2];
int file_align_sector[2];
int file_align_page[2];
int normal_image_base[2];
int specific_image_base[2];

/*/
/*
 *
 */
int main(int argc, char **argv)
{
char fname[1024], *cp;
int fd = -1, tmp, isexe;

while (close(fd),
   fd = -1,
   fgets(fname,sizeof(fname),stdin)
)
{
cp = strpbrk(fname,"\r\n");
if (cp)
*cp = 0;

fd = open(fname,O_RDONLY);
if (!fd) {
if (errno==EISDIR)
continue;
perror("open");
return 1;
}

/* get the DOS image header */
tmp = read(fd,&imghdr,sizeof(imghdr));
if (tmp<0) {
if (errno==EISDIR)
continue;
perror("read doshdr");
return 1;
}
if (tmp


Re: Speeding up wineserver syncronization objects with shared memory

2001-03-08 Thread David Howells


> Page alignment is needed for the address in memory, not for the offset
> inside the file on disk; since section virtual addresses in PE files
> are always page-aligned the memory address is never a problem. The
> only problem comes from the alignment of the data inside the PE file,
> and this is where we only need block-size alignment to make mmap
> possible.

Not so... The file offset must also be page aligned!

Try the following program:

#include 
#include 
#include 
#include 

int main(int argc, char **argv)
{
void *addr;
int fd;

fd = open("/bin/sh",O_RDONLY);
if (fd<0) { perror("mmap"); return 1; }

addr = mmap(NULL,512,PROT_READ,MAP_PRIVATE,fd,argc==1?512:4096);
if (addr==MAP_FAILED) { perror("mmap"); return 1; }

return 0;
}

If you don't run it with an argument, it fails (Invalid Argument), and if you
do give it an argument, it works.

If you look at the kernel:

[arch/i386/kernel/sys_i386.c]
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
struct mmap_arg_struct a;
int err = -EFAULT;

if (copy_from_user(&a, arg, sizeof(a)))
goto out;

err = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;

err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
return err;
}

Note that "a.offset" (the file offset) is checked for page alignment. Note
also that the internal kernel routine do_mmap2() deals with the offset in
terms of pages, not bytes.

David





Re: Speeding up wineserver syncronization objects with shared memory

2001-03-07 Thread David Howells

> Note that we are no longer doing that in the latest versions; the file
> descriptor is only transferred once,

Fair enough... I see that ZwClose/NtClose isn't actually a problem (since
unlike most other Zw* calls, it can't affect other processes).

Oh... I see how you're doing it... sending the handle->fd translate request to
the server, which sends a response saying you've got it cached; then using
dup() locally to emulate the old behaviour; and then closing the fd.

So this saves you the cost of the fd transfer net packet. Though you still
have to do the two context switches, which is my main contention.

> and all further requests are done on a pipe which is faster than a socket.

True, but I'd have thought that the context switches involved are still a cost
you can't get rid of so easily. Out of interest, how do you plan on doing the
locking stuff for Read/WriteFile? Cache it locally? It is unfortunate, but you
can't really make use of UNIX file locking, since this is mostly advisory and
as such doesn't actively stop read/write calls.

> The kernel module itself may be hard to do incrementally, but you
> should really consider reusing the existing server API so that your
> module can be plugged in easily. For instance your module entry points
> should be the same as the server requests, and use the same request
> structures.

What? Miss the opportunity to implement "int 0x2e" directly? *grin*

Seriously, though, whilst this'd be a lot easier in many ways (and it would
allow you to avoid the context-switch penalties), you wouldn't be able to take
full advantage of the available support in the kernel, which is more capable
than the standard UNIX userspace API suggests.

It'd still have to paste handles to fds for most file operation calls, and
you'd still have the PE Images soaking up a fair amount of memory.

If this is what you want, then it might be better done as a network protocol
module that just pretends to be a wineserver, and supports the same
read/write/sendmsg/recvmsg interface. (It'd have to be a network protocol to
be able to get sendmsg/recvmsg calls):

int serv = socket(AF_WINE,SOCK_STREAM,0);
short addr = AF_WINE;
connect(serv,(struct sockaddr*)&addr,sizeof(addr));

> I still think that it should be possible to improve that by a small
> kernel hack. It will never be as fast as doing everything in the
> kernel of course, but it may just be fast enough to avoid the need to
> reimplement the whole server.

If you want to suggest exactly what you'd like to see as a hack...

> Have you measured how many dirty pages you can avoid with your change?
> It seems to me that in most cases, when the dll is loaded at its
> preferred address, the number of pages made dirty by the fixups should
> be quite small anyway.

As far as I've observed (I've got Win2000 available), most Windows DLL's have
512-byte (sector) alignment internally, _not_ 4096-byte (page) alignment for
the sections. This means that the separate sections can't be mmap'd (or else
they'd lose their required relative relationships):

VIRTUAL_mmap()
{
...
/* mmap() failed; if this is because the file offset is not*/
/* page-aligned (EINVAL), or because the underlying filesystem */
/* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */
...
}

This appears to happen a lot. And then _all_ the pages in that section are
dirty, irrespective of whether fixups are done or not.

Also, since DLLs and EXEs are not compiled as PIC (the MSDEV compiler not
having such an option as far as I can recall), the fixup tables usually seem
to apply to just about every page in the code section.

I'll have to write a small program to collect some statistics:-) 

As for the DLL being loaded at it's preferred address, the kernel module jumps
around the fixup stuff, and doesn't even consider trying to perform it.

Plus pages that have been altered by the fixup code are actually marked
_clean_ by the VM subsystem, and can thus be simply discarded when physical
memory needs to be reclaimed.

David





Re: Speeding up wineserver syncronization objects with shared memory

2001-03-06 Thread David Howells

Gavriel State <[EMAIL PROTECTED]> wrote:
> As it stands, your approach won't be useful for general Wine usage until
> you've got *everything* done.

True. But I think there are valid reasons for doing it this way.

One major problem is handles. Either the kernel must allocate all handles, or
userspace must allocate all handles. Take something like the implementation of
DuplicateHandle() - dead easy really in kernel space, including duplication to
another process.

If userspace tells the kernel to use handle X for a mutex, say, and handle Y
for a semaphore, then userspace still has to go to atomic management code to
(a) allocate a handle, and (b) access a handle. And to implement cross-process
duplication, you either need some sort of interrupt & IPC mechanism, or an
external process (the wineserver). This being the case, you lose any gains by
putting the stuff in-kernel.

Alternatively, if userspace is allowed to implement arbitrary handles that are
allocated by the kernel, then the kernel waiting mechanism can get a little
tricky. However, that said, for non-waitable objects, this might not be so
bad. In fact, I'm planning on implementing the registry access handles this
way and may well do some of the process and thread control this way too.

Furthermore, the kernel would have to be given object handles not object
pointers, otherwise you have a gaping security hole.

And another major problem is context switches... they are horribly expensive
really. They currently make Wine with at least 20 times the system call
latency that the kernel method is capable of.

> And then there will be boatloads of debugging to do.

Perhaps not as much as you think... I'm doing as much debugging as I can as I
go along, just making sure the kernel objects work as I'd expect (not
necessarily the same thing, true, as having "compatible" behaviour).

> If there's any way that you can implement your kernel module more within the
> context of the existing server architecture - replacing objects on a piece
> by piece fashion rather than all at once - that might make it easier to
> adopt.

See above for why the piece-by-piece method is difficult.

One alternative would be to invent a new network protocol (say AF_WINE), but
that again requires a complete implementation before it is really useful.

> For example, you might try implementing the core object/handle management
> and waiting code in the kernel module, and have the wine server rely on the
> kernel module for that low-level functionality.

By this, do you mean actually having the wineserver process talk to the kernel
module on behalf of the Wine application?

> Waiting for objects would be implemented on the client side through a call
> to the kernel module. 

That's what I'm currently doing, though it's not fully implemented yet.

> When something needs to be done with an object, we would call either the
> wineserver or the kernel module, depending on how that object is
> implemented.

> For example, you could do mutexes entirely within the kernel module, but
> leave file objects on the wine-server side initially.

My main gripe is the slow speed of access to files... Every Read/WriteFile
goes to the wineserver to convert the handle into a file descriptor and to
check for locking. The FD is then passed back over a UNIX domain socket, used
once and then closed.

I suspect it can't really be done otherwise, particularly if ZwCloseObject (or
whatever it is called) is implemented, since this allows handles in another
process to be closed.

Actually, I've done a fair amount of the file object stuff... Most of it
involves mapping down to a "struct file *", which is how the kernel views
files, and then invoking appropriate kernel method.

> In my experience Alexandre far prefers incremental change to kind of
> approach you're taking.  Using that kind of approach will improve the
> chances that your code will make it into Wine at some point.

Hmmm... It's difficult to determine how to do it incrementally without making
for even more work, but I think I know what you mean.

> One thing I've been wondering that you might be able to answer is this:
> exactly why is the current Wine Server architecture so slow?  Is it just the
> context switching?

Context switching is the main element of it. Going to the wineserver and back
again just for a ReadFile() call or a Wait*() function incurs a fairly serious
penalty (particularly on an X86, I think). Plus there's no requirement for the
kernel to pass the remains of your timeslice to the wineserver and back
again. Also, you have to bundle lots of data through AF_UNIX network packets
and/or copy lots of data into and out of _shared_ memory without killing other
threads.

One of the problems with the context switch is that you have to flush all the
CPU caches, muck around with the MMU and execute scheduling algorithms.

> Is it that the kernel isn't giving the wineserver a high enough priority
> once the client blocks after having written to

Re: Speeding up wineserver syncronization objects with shared memory

2001-02-28 Thread David Howells


I've got a lot of the wine support kernel module written now. Its system call
latency seems to be down at near half that of Win2000 for mutexes, though
there's no guarantee that my benchmark programs produce meaningful numbers.

I've also got PE Image mapping done (with pages fixed up on demand and marked
as discardable). So if anything, Wine might want to steal that if the module
as a whole is not used. This bit requires virtually no changes to the kernel
itself, just half a dozen or so extra symbols to be exported.

The module image size stands currently at about 30K.

Status:
PARTSTATE
==  ==
General object infrastructure   done
HANDLE infrastructure   mostly done
Waiting calls   partly done
Exception handling  not done
Win32 error handlingnot done, uses UNIX errno
UNICODE handlingignored, all ASCII
Security handling   ignored

Mutex objects   done
Semaphore objects   done
Event objects   done
File objects (synchronous access)   mostly done
File objects (asynchronous access)  not done
Shared memory objects   mostly done
Process objects slightly done
Thread objects  slightly done
Registry objectsnot done
NT Port objects not done
NT Token objectsnot done
W2K Job objects not done
Net Communications  not done

userspace access libraryup to date
strace  mostly up to date

Cheers,
David





Re: VxD and kernel module

2000-09-26 Thread David Howells


Peter Hunnisett <[EMAIL PROTECTED]> wrote:
> Just a question. With the wine server running as a linux kernel module 
> would we be able to support native VxDs? I'll be honest that I don't 
> understand the transition between rings but I'm guessing that it must 
> involve a trap of some descript which could then be passed off to the 
> kernel module to run in a more priviledged mode.

It _might_ be possible to extend the kernel module to provide DDK APIs for VxD
and NT drivers (more so for the latter case), but it probably wouldn't be
easy. Certainly, the kernel module would be able to provide handle support,
registry access, etc., but not swappable kernel memory for now.

I have wondered myself about what'd be necessary to support NT/W2K display
drivers in the Linux kernel, as that might make it possible to build XFree86
around them.

David Howells



Re: wine-cvs mailing-list doesn't seem to work

2000-09-26 Thread David Howells

I've noticed that the wine-devel has gone very slow. In fact, wine2.winehq.com
has ben refusing connections and the backup mailserver at Corel has been
bouncing messages for no obvious reason.

I don't know whether this helps

David Howells



Would it be possible...

2000-09-15 Thread David Howells


Would it be possible for me to store a copy of my kernel module code on
winehq? Or should I find somewhere else (eg: sourceforge)?

Cheers,
David Howells




Re: RFC - Winelib constructor init problem

2000-09-08 Thread David Howells


Patrik Stridvall  wrote:
> Looking at the message again,...

Fair Enuff.

> Personally think that LD_PRELOAD should only be used for tests
> and for kludging problems that need a fix _now_, not something
> that should be used in normal cases.

I was thinking along the lines of just getting it up and running with Wine for
the moment.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-08 Thread David Howells

Patrik Stridvall <[EMAIL PROTECTED]> wrote:
> FYI I read linux-kernel too from time to time, but I don't
> subscribe to it. I read it through the archive.

Well, I wasn't to know. And in any case the message was meant to be copied to
wine-devel, but it didn't work, somehow.

> So what is the next step?

Well, I'll keep on writing it, see how it goes... It occurs to me, though,
that it can be used with wine through the LD_PRELOAD functionality.

One thing that has to be worth doing is putting it up for ftp/CVS somewhere,
probably separate from Wine, and probably giving some other people write
access to it.

> PS. Why did you mail only me in private?

See above.

David Howells




Linus Torvalds: Re: [RFC] Wine speedup through kernel module

2000-09-08 Thread David Howells


--- Forwarded Message
To: [EMAIL PROTECTED]
From: [EMAIL PROTECTED] (Linus Torvalds)
Subject: Re: [RFC] Wine speedup through kernel module
Date: 7 Sep 2000 16:02:10 -0700

In article <[EMAIL PROTECTED]>,
David Howells  <[EMAIL PROTECTED]> wrote:
>
>I've done an implementation of some of the Win32 "system calls" in a kernel
>module in an attempt to speed up Wine.

Hmm.. I have this feeling that it would be much nicer to just implement
the NT system calls directly.

We used to have the iBCS2 project, and I was actually considering making
it part of the standard kernel when it started becoming a non-issue
simply because there started to be more native Linux programs than iBCS2
programs. 

And we've already had the vm86 mode and the BIOS trap stuff speedups for
DOSEMU for a long time.

It looks like if you want to do this, it would be better to just try to
do it outright, and have the same kind of "emulate the ones we know
about and care about performance" in the kernel that we already have
with the vm86 mode emulation.

I wouldn't be adverse to supporting Wine better - as long as it's fairly
cleanly separated. This doesn't look too bad.

Linus
- -
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

--- End of Forwarded Message




Re: RFC - Winelib constructor init problem

2000-09-06 Thread David Howells


Alexandre Julliard <[EMAIL PROTECTED]> wrote:
> I told you what I wanted: basically a pipe with slightly different
> semantics; no need to touch the scheduler for that. It should be
> pretty easy to code for an experienced kernel hacker (which I'm not),
> and then we can run benchmarks and see if the idea has any merit at
> all.

Perhaps you'd consider taking a look at the RPC mechanism that I designed and
mostly implemented... It currently passes an address from the client to the
server and accepts an integer and an error number back. What I haven't had
time to write yet are the ptrace-style read/write functions that will allow
the server to gain access to the client's memory space. An extra pair of
functions could also be provided to paste fd's between the client and server.

Patrik Stridvall <[EMAIL PROTECTED]> wrote:
> Seriously, as I said above, I consider a Linux kernel Wine server
> nothing more than a marketting gimmick. I would very much prefer
> the user space Wine server to be maintainable and robust rather
> than fast. 99.99% of all application that are likely to be run
> under Wine will not care if mutexes are 900% slower as long as
> they have the correct semantics.

What I'm most concerned about with wine is the fact that every time a file
operation is issued, the client makes a call to the server to convert the
Win32 file handle into a UNIX fd (via sendmsg/recvmsg), which gets used once
and then discarded.

I've seen programs that do a lot of I/O (for instance PVCS) hammer the server
lots with requests for file handle conversion, and so they run quite a bit
slower on Linux than on Windows.

I do also wonder about the server running out of fd slots, but I don't think
that is too much of a problem.


Of course the biggest reason for doing this is the technical challenge... and
of course proving to the Windows nutters around that Linux can do Windows
system calls faster than Windows itself *grin*.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-05 Thread David Howells

As promised... I've attached a copy of the latest source for my kernel module.

Note that I've implemented some support for file objects:

 CreateFile, ReadFile, WriteFile, SetFilePosition, SetEndOfFile,
 FlushFileBuffers

However, I'm not sure it's necessary to go this far... just being able to
attach fd's to handles and extract fd's from handles may be sufficient.

I've also partially implemented the RPC mechanism I mentioned yesterday (which
might also interest Alexandre for his idea of improved RPC). At the moment,
all it can do is pass an address to the server and get an integer back. I
didn't have time to write the read/write functions that directly access the
client's memory space.

It took longer than I thought to work out how to do a rendezvous between two
processes and three objects without incurring deadlock or oopsing if one of
the objects went away.

David Howells


 wine server module


Re: RFC - Winelib constructor init problem

2000-09-05 Thread David Howells


Patrik Stridvall <[EMAIL PROTECTED]> wrote:
> Nothing specific, just a general feeling that some sort of selective
> yielding is not a good idea and in order to avoid DoS something
> not unlikely costly must be done to have a fair scheduling.

Plus, I don't think you can do selective yielding at the moment. You might be
able to get around the DoS attack by having the scheduler limit the amount of
time you can trade to the remainder of your timeslice, after which the process
to which you yield gets scheduled out anyway. But it sounds horribly complex.

> Regardless of what syscalls you have, if you want good latency you must
> have a guarantee that in average that kernel will schedule the server
> after the client call as well as the reverse.
> 
> For a lightly loaded machine this is likely to happend automatically
> since few other processes want to run. But for a heavily loaded machine
> you probably must have some sort of selective yield otherwise you will
> get very bad latancy when other process get time slices in between.

Agreed.

> I'm not a kernel expert but I have a general feeling that you will
> never get good performance unless the kernel gives you some kind
> of selective yield guarantees which is not unlikely to be costily
> for scheduler.

Agreed... but you still have to pay the penalty on context switches.

> IMHO putting the speed critical NT kernel object in the kernel
> is a much better and more realistic solution.

Also agreed. The kernel has good support for synchronisation, providing a
wealth of types of synchronisation object.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-05 Thread David Howells


Alexandre Julliard <[EMAIL PROTECTED]> wrote:
> Patrik Stridvall <[EMAIL PROTECTED]> writes:
> 
> > Everything that is speed critical should be in kernel,
> > things that are not should not. Trying to do it
> > some other way is doomed to failure I think.
> 
> That's *exactly* what I'm proposing: the speed critical part (the
> request mechanism, since it is used for all server calls) in the
> kernel, all the rest in user space.

But the time and CPU usage overhead comes from the context switches and the
waiting for the "other" process to be scheduled.

We can improve the client memory access mechanism to reduce the whole thing to
only two context switches, but they still impose a severe penalty.

> Obviously I'm not suggesting that we add these two functions as system
> calls; this is only the conceptual interface. The actual
> implementation should probably be based on file descriptors; basically
> it is a kind of pipe with slightly different semantics (you could even
> achieve most of that with normal pipes, but you'd need to always
> transfer 4096 bytes to keep the buffer full which would be a bit
> slow).

Not nice... Imagine you want to just grab a mutex... you'd have to transfer 4K
of data each direction, the vast majority of which would be totally wasted. I
have to agree with Patrik again, sendmsg+recvmsg are better options there.

A better way to do this is just to pass an address in the clients VM and have
the server access it directly.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-05 Thread David Howells


Alexandre Julliard <[EMAIL PROTECTED]> wrote:
> I think what we need is:
> 
> - on the client side, a wake_server_and_sleep() call that combines the
>   write()+read() on the socket in a single syscall.
> 
> - on the server side, a wake_client_and_wait_for_next_one() that wakes
>   the client whose request was last processed, and waits until some
>   other client sends a request.

This is fairly pointless... the Linux system call overhead isn't all that
major - issuing separate send & receive calls loses you very little. Beyond
the fact that the server may be busy doing something else, the real killer is
the pair of context switches and the fact that there is no guarantee that the
server will immediately be scheduled after the client, and the client again
after the server.

Indeed, it may be necessary to swap the server back in, depending on system
load.

> This should enable doing a complete server round-trip with only two
> syscalls (one in the client one in the server), and avoid any
> unnecessary context switch.

Like the two switches to get to the server and back again?

> If we combine this with an efficient way to read/write the client
> memory space from the server, I think we should be able to achieve
> good performance while still reusing nearly all the existing code.

True, some sort of ptrace-type access mechanism may help speed things up
without tying up ptrace.

> And if the mechanism is small enough and generic enough, we can even
> hope to have it included in the standard kernel, which I doubt would
> ever be possible with the complete server kernel module.

As Patrik implied... Unlikely (though he said it more eloquently).

David Howells




Re: RFC - Winelib constructor init problem

2000-09-04 Thread David Howells

> No, I don't think it has anything to with exec_domain/personality.

All that this has to do is determine how some signals and syscalls are
handled, but you are probably right.

> What happens if the module goes away?
> The application segfaults I hope.

Depends... if you don't manage it properly then "OOPS"!

Otherwise, it's a matter of making sure that the module _won't_ go away - make
the module register and unregister a handler and its "module definition"
structure (similarly to how the vfs deals with things).

This means:

 (1) A new call can't start if there is no handler registered.

 (2) Whilst a call is in progress, the module's usage counter is kept
 incremented.

 (3) Obviously, the module can't be removed whilst the counter is non-zero.

 (4) There is protection available to make sure you can't tweak a module count
 whilst the module is being loaded/unloaded (so you can't slip in a new
     usage between counter-is-zero-check and actual-removal).

David Howells




Re: RFC - Winelib constructor init problem

2000-09-04 Thread David Howells


> Note that if you layout the call structure _exactly_ the same
> way as the stack layout (which is fixed for all Windows API functions).
> You will get an even faster call mechanism that you currently have.
> Just load a register with the call id another with the offset:ed
> stack pointer and then sys call.
> 
> I wonder how many percent faster that will be?

Out of interest, did you get this idea from looking at the source code I sent
out earlier? It's changed since then... I'll have to distribute my revised
stuff tomorrow.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-04 Thread David Howells


Patrik Stridvall <[EMAIL PROTECTED]> wrote:
> I think it is because the Linux syscall mechanism is faster.
> In any case a totally meaningless benchmark since there is
> no practial use in doing a tight mutex loop.
> 
> However, it might be useful for marketing Wine. :-)

True... It is however 900% or better faster than straight wine.

> The registry is a file system (almost). The main difference
> is that the "directories" can have content as well.
> 
> It would be nice to be able to mount (loopback mount) the
> registry files. This means that 

Are you thinking of mounting Windows registry hives directly? If so, don't
forget: (1) the windows registry spans several hive files, (2) hives can be
added by user processes, (3) what about change notifications, (4) what about
dynamic data, and (5) what about meta-data (type, etc.).

Admittedly, some this might be solved by a filesystem, particularly if you can
mount registry filesystems on registry filesystems (equivalent to adding
hives) and use symbolic links to emulate registry symlinks.

> The fact that "the set of functions available in the two
> spaces is different" does not nessary mean that sharing
> source is ruled out it depend largely on how many #ifdef
> you need to hide the differences. Note that many things
> can be hidden in the header files.

Hmmm... You have to emulate all the locking stuff it you want to be able to
multithread your userspace-only server.

Actually, what you can probably do is write the server as a kernel module, and
then emulate the kernel services in userland. I did this to some extent in a
small testbed program that I wrote so I could trace the kernel module easily
with gdb.

> Yes, I think should have a special syscall for this.
> ...
> However, I think, with the exception of the overhead,
> that the ioctl interface is good in principle.
> 
> Just add a syscall called
>   int winecall(int id, void *data);
> this gives flexibillity. We can add as many new "winecall":s
> as we like using this interface.

We'd have to persuade Linus to part with one. Maybe attaching it to the
exec_domain/personality stuff.

We'd also have to be _very_ careful using it if the wineserver is in a module,
otherwise the module might go away whilst we're using it, but that shouldn't
be a problem.

> I use ioctl because (a) it already exists, (b) I don't have to change the
> kernel to use it, and (c) I'm using a file descriptor to control the lifetime
> of the handle map.
> 
> Somebody earlier mentioned using the mechnism that NT (int 2e IIRC),
> the problem with this is that IIRC the syscall numbers are not
> constant they are dependent on the version of the NT kernel.
> They are IIRC sorted in alphabetic order. This means that the
> native NTDLL.DLL will not run under Wine regardless so it
> is not much use in doing that.

Plus, you'd have to be able to change the interrupt table, not just a system
call table entry, since NT goes through a currently unimplemented interrupt.

> Note that if you layout the call structure _exactly_ the same
> way as the stack layout (which is fixed for all Windows API functions).
> You will get an even faster call mechanism that you currently have.
> Just load a register with the call id another with the offset:ed
> stack pointer and then sys call.
> 
> I wonder how many percent faster that will be?

I rewrote the userspace interface to work this way, giving me 10%-20% extra
performance.

One thing that I had to be careful of though is how the corresponding
structures are laid out. Two BOOL arguments in a row in a function call
parameter list take 8 bytes, but in a structure take only two. So I came up
with something like:

#define __pad__ __attribute__((aligned(4)))

struct WiocCreateEventA {
   LPSECURITYATTRIBUTES __pad__ lpEventSecAttr;
   BOOL __pad__ bManualReset;
   BOOL __pad__ bInitialState;
   LPCSTR __pad__ lpName;
};

When any userspace stub function invokes the ioctl, it passes the address of
the first argument to the kernel, which casts it to the appropriate structure
type.

> PS. Perhaps you should ask Linus about reserving a syscall for
> Wine before 2.4 is released in order to miniminze support 
> problems.

Yep... assuming we want to do this.

David Howells




Re: RFC - Winelib constructor init problem

2000-09-04 Thread David Howells

Alexandre Julliard <[EMAIL PROTECTED]> wrote:
> The kernel module approach is interesting, but I'm afraid it's not
> really practical to reimplement the complete server in the kernel,
> unless we can somehow build both the kernel module and the user-mode
> server from the same sources.

I have to agree with that... I have implemented mutexes, events, semaphores
and some of the file handling in a kernel module, plus CloseHandle and most of
WaitForMultipleObjects. I can see also process and thread handling and socket
handling working quite well, and I might even be able to manage overlapped
I/O.

(I have to report, I think, that I rewrote the userspace interface, and I
 managed to get something like a 20% better turn around time in a tight mutex
 loop than Win2000 executing the same loop *evil grin*).

However, I don't think that, for instance, the registry is particularly
suitable to Linux kernel space. If it was stored in specially allocated slab
memory caches (making it trivial to dispose of), with all the keys as unicode
and linkage blocks forming a tree structure, it would take rather a lot of
unswappable memory.

As for building from the same sources, I don't think that's practical either,
since the set of functions available in the two spaces is different (though
you can make system calls from kernel-space, I don't recommend it in this
case).

> An intermediate approach that may be worth investigating is to keep the
> server in user-space but implement a faster request mechanism with a small
> kernel module; Unix sockets are not very well suited to the request/reply
> model that we need, and I think it should be possible to make the
> communication much faster with a specialized kernel call.

Basically, I too am thinking of an intermediate approach...

(1) Put the bits that call the server all into one place in the source (as is
mostly done now). Note that the kernel module I have produced _entirely_
implements the Mutex, Semaphore and Event system calls, so things like
CreateMutex and WaitForMultipleObjects would have to go in there.

(2) The kernel module takes over handle management, with no userspace
intervention required. Reference counting, handle number allocation,
etc. all done in kernel space.

(3) Provide a sort of RPC mechanism for those services that are impractical to
implement in kernel space (such as the registry). I've outlined such a
mechanism in an attachment to this message.

And some miscellaneous optional extra bits:

(1) We could use a spare system call to provide access to the kernel module,
rather than using ioctl as I do now. This will bypass the overhead of
ioctl looking for standard, internal commands to deal with first.

(2) Provide calls to map UNIX fd's into file handles, and vice versa.

(3) Make CreateFileHandle walk the directory tree itself (rather than relying
on filp_open in the kernel), thus allowing much faster support for
case-independent matching.

And for cases where a kernel module can't be used (such as a non-Linux
platform) switch to a different directory in the source tree, that uses the
current UNIX socket based approach.

David Howells


Here's an idea for RPC mechanism. I think this should be fairly easy to
implement, given the basic kernel module I've already got.

This is, I think, very similar to the Solaris door mechanism.

SERVER IMPLEMENTATION
=
(a) Use the handle management capability of the kernel module to look
after keeping track of requests and replies in the server.

(b) Have the server create a Service object, which it can then wait on
and accept requests through (similar to server sockets). Multiple
threads will be able to wait in this way.

hServer = CreateWineService("registry-access");
WaitForMultipleObjects(1,&hServer,0,INFINITE); /* optional */

void *params;
hRequest = AcceptWineServiceRequest(hServer,¶ms);

(c) Either:
(1) allow the server process to access the memory space of the client
via a direct ptrace-type mechanism. This should be very fast, and
require minimal copying.

RegistryRequest rr;
ReadWineServiceData(hRequest,params,rr,sizeof(rr));
WriteWineServiceData(hRequest,...);

(2) or actually have the service request acceptor take a buffer into
which the request is copied, and then have the request reply
function take a buffer which holds the reply.

(d) Finally, have a reply/result function that closes the handle and
finishes the request:

ReplyWineServiceRequest(hRequest,reqerrno,result);

CLIENT IMPLEMENTATION
=
(a) As far as the client is concerned, some requests will be handled
internally inside the kernel module, for instance, RegOpenKey. The
kernel module may make a handle for use by the client, keeping some
context informa

Re: possibility for massive wineserver speedup

2000-08-30 Thread David Howells

> There's documentation included in the attached archive, including some rough
> preliminary benchmarks. As a quick off the cuff reading, it beats Win2000 by
> ~3% and Wine by ~900% on a dual CPU box.

Actually, on one of the benchmark programs, it beats Win2000 by ~20% not ~3%,
assuming I've calculated the percentages correctly.

I've attached the benchmark data to the bottom of this message.

David Howells
-

Machine: Dual PII 400MHz, 384Mb RAM
Linux compiler: gcc version 2.96 2724
Windows compiler: MSDEV 6

FIVE THREADS/PROCESSES, ONE MUTEX
=

rapidmutex.c - Linux 2.4.0-test7
[2] obtained the mutex 62525 times (15631 times per second)
[1] obtained the mutex 64156 times (16039 times per second)
[0] obtained the mutex 64909 times (16227 times per second)
[3] obtained the mutex 70250 times (17562 times per second)
[4] obtained the mutex 67967 times (16991 times per second)
  ==
  329807 over 4s period

rapidmutex-win.c - Win2000
[0] obtained the mutex 54563 times (13640 times per second)
[1] obtained the mutex 54553 times (13638 times per second)
[2] obtained the mutex 54529 times (13632 times per second)
[3] obtained the mutex 54503 times (13625 times per second)
[4] obtained the mutex 54481 times (13620 times per second)
  ==
  272629 over 4s period

rapidmutex-win.c - Wine-2716/Linux 2.4.0-test7
[0] obtained the mutex 6753 times (1688 times per second)
[1] obtained the mutex 6743 times (1685 times per second)
[2] obtained the mutex 6725 times (1681 times per second)
[3] obtained the mutex 6719 times (1679 times per second)
[4] obtained the mutex 6714 times (1678 times per second)
  =
  33654 over 4s period

FIVE THREADS/PROCESSES, FIVE MUTEXES (Hungry philosophers problem
=

fivemutex.c - Linux 2.4.0-test7
[0] ate 45638 times (11409 times per second)
[1] ate 51196 times (12799 times per second)
[2] ate 53221 times (13305 times per second)
[3] ate 79667 times (19916 times per second)
[4] ate 61109 times (15277 times per second)
   ==
   290831 over 4s period

fivemutex-win.c - Win2000
[0] ate 38675 times (9668 times per second)
[1] ate 50682 times (12670 times per second)
[2] ate 56600 times (14150 times per second)
[3] ate 97662 times (24415 times per second)
[4] ate 39870 times (9967 times per second)
   ==
total  283489 over 4s period

fivemutex-win.c - Wine-2716/Linux 2.4.0-test7
[0] ate 4965 times (1241 times per second)
[1] ate 5664 times (1416 times per second)
[2] ate 5729 times (1432 times per second)
[3] ate 5748 times (1437 times per second)
[4] ate 4954 times (1238 times per second)
   =
   27060 over 4s period




Re: possibility for massive wineserver speedup

2000-08-30 Thread David Howells


Jeremy White <[EMAIL PROTECTED]> wrote:
>Wow.  This is the coolest new idea I've seen posted
>to wine-devel for a while.

Thanks *grin*.

>I suspect it has many hurdles and may never be practical with Wine,
>but I would really love to run winbench with Wine
>and have the numbers be faster than that of NT...
>
>(I'm not going to try to address the issues; I suspect
>that better minds than mine [e.g. Alexandre] will weigh
>in with a more complete analysis).

Oh, I don't know, I think in some ways it is very practical. My thought is
that anything it can't handle easily or quickly can be passed transparently to
a server process to be done in userspace (ie: registry maintainance and
access).

As for not currently being compilable against Linux 2.2, I think that can be
solved fairly easily.

>Do you mind if I ask what prompted you to undertake this
>process?

I like kernel programming, I'd like to see Wine go faster (I've tried stracing
it and seen the absolute mass of wineserver interactions flying past).

On a more practical note, I run the PVCS command line tools (version control)
under Wine at work, and they could be faster (they're implemented in threaded
Java - yuk), so I recon this could speed them up a bit.

I also occaisonally run the MSDEV command line compiler under Wine, and that
could be a lot faster too.

David Howells




possibility for massive wineserver speedup

2000-08-29 Thread David Howells

Well, I've made a start on a kernel module implementing some wineserver-type
functionality, and I think that I've reached a reasonable point to put it up
for discussion.

Note that you will need one of the later development Linux kernels to use it
with (I use 2.4.0-test7) - I've attached the a tar-bzip2 archive of the code
to this document.

At the moment it does the following:

CreateEvent
OpenEvent
PulseEvent
ResetEvent
SetEvent
CreateMutex
OpenMutex
ReleaseMutex
CreateSemaphore
OpenSemaphore
ReleaseSemaphore
WaitForMultipleObjects (mostly)
CloseHandle

Unfortunately, it can't actually be integrated into Wine just yet, since it
only supports three of the many 'kernel' object types, and WaitFor*() can't be
shared between implementations.

There's documentation included in the attached archive, including some rough
preliminary benchmarks. As a quick off the cuff reading, it beats Win2000 by
~3% and Wine by ~900% on a dual CPU box.

Note that WaitForMultipleObjects() is implemented internally in the same way
as poll and select, and thus is a restartable system call (can be interrupted
by signals).

I've pasted part of the Why? section out of my documentation:

WHY
===

Because the current wineserver interface involves each wine process making a
socket connection to a separate server process, which then arbitrates access to
synchronisation objects and various other things.

All this involves message passing and lots of process context switching
(slow). By moving this into the kernel, advantage can be taken of kernel
services for handling synchronisation, scheduling and concurrency.

As an additional minor benefit, the "strace" program can be modified to read
these specific system calls.

===

So comments please...

Have fun,
David Howells


 wineserver kernel module source


Re: why does wine use stdin, stdout & stderr streams from wineserver?

2000-08-23 Thread David Howells

> did you wrote a .spec file specifying this is a console app =3F

A spec file? MSDEV doesn't use such beasts, does it? Do you mean a .def file?
But that doesn't seem to be much use either.

However, I have tried compiling with "/D_CONSOLE /link /SUBSYSTEM:CONSOLE" and
also generating a complete console project from MSDEV's IDE, and the same
thing happens in all cases - output goes through wineserver.

David




Re: why does wine use stdin, stdout & stderr streams from wineserver?

2000-08-23 Thread David Howells

'Scuse me for being persistent, but can someone answer the following:

Why does a simple program like the following use wineserver's stdin/out/err
channels, not wine's?

#include 
int main()
{
printf("hello\n");
return 0;
}

I've compiled this with MSDEV6 and run it under wine in a different xterm to
where wineserver was running, and the output definitely appears to come out of
wineserver (the appropriate fd is passed over a UNIX domain socket for every
I/O operation wine performs).

Marcus Meissner wrote:
> They could have been changed using SetStdHandle().

Not so... I put a breakpoint in wine's implementation of this, and it
execution didn't pass through that.

> And the plain stdio stdin/stderr/stdout are not affected.

Also not so... see above test program.

Thanks,
David Howells




Re: wine .spec file autogenerator

2000-08-21 Thread David Howells

> - the shell32 exports many functions by ordinal withou a name.
>  Your tool likely can't cope with it - or it would need to use *.dbg 
> and *.pdb files to get symboles from. (have not tryed it jet)

It can cope with it - or at least it emits a symbol constructed from the name
of the DLL and the ordinal.

Furthermore, the whole thing agrees with the output from "dumpbin /exports",
except that that doesn't construct names for anonymous ordinals.

David




wine .spec file autogenerator

2000-08-18 Thread David Howells

Since no-one out there seems to have one, I've written a small perl script
that reads the output of "objdump -x" run on a windows DLL and turns it into a
.spec file with all the function stubbed out (handy when you want to deal with
a DLL with over a thousand entry points).

However, I've noticed that it doesn't appear to correlate with the already
existing shell32.spec file based on a dump of the WinNT4 shell32.dll (at least
as far as ordinals go). Can anyone explain this?

David Howells

#!/usr/bin/perl -w
#
# Format:
#objdump -x  | genspec.pl >.spec
# (using objdump from binutils-2.10)
#

#
# search for the beginning of the import table specification
#
while (<>)
{
chomp;
if ($_ =~ /^The Import Tables/ ) { last; }
}

#
# pull imported DLL specifications out of the import table
#
my @imports;
while (<>)
{
chomp;
if ($_ =~ /^The Export Tables/ ) { last; }

# pull out an import specification
if ($_ =~ /^\tDLL Name:/ )
{
$_ =~ s/^[^:]*[:][ ]*//;
$_ =~ y/A-Z/a-z/;
push(@imports,$_);
}
}

#
# search for the beginning of the export address table
#
$name = "";
$ordbase = 0;
while (<>)
{
chomp;
if ($_ =~ /^Export Address Table/ ) { last; }
if ($_ =~ /^Name/ ) { @_ = split; $name = $_[2]; }
if ($_ =~ /^Ordinal Base/ ) { @_ = split; $ordbase = $_[2]; }
}

#
# pull imported DLL specifications out of the import table
#
my %exportvmas;
while (<>)
{
chomp;
if ( $_ =~ /^ *$/ ) { last; }

# pull out an import specification
@_ = split("[][]");
$_[1] =~ s/ //g;
$_[4] =~ s/^ *//;
$_[4] =~ s/ .*$//;
$ord = $_[1] + $ordbase;
$exportvmas{$ord} = $_[4];
}

#
# search for the beginning of the ordinal naming table
#
while (<>)
{
chomp;
if ($_ =~ /^.Ordinal.Name Pointer. Table/ ) { last; }
}

#
# pull ordinal -> name mappings out
#
my %exportnames;
while (<>)
{
chomp;
if ( $_ =~ /^ *$/ ) { last; }

# break into bits
@_ = split("[][]");
$_[1] =~ s/ //g;
$_[2] =~ s/ //g;
$ord = $_[1] + $ordbase;
$exportnames{$ord} = $_[2];
}

###
#
# render the spec file
#
$name =~ y/A-Z/a-z/;
$dll = $name;
$dll =~ s/.dll//;

print "name\t" . $name . "\n";
print "type\twin32\n";
print "init\t" . $dll . "LibMain\n";
print "rsrc\t" . $dll . "rsrc\n";

print "\n";
foreach (@imports)
{
print "import " . $_ . "\n";
}

print "\n";

@exports = sort {$a <=> $b} keys %exportvmas;
foreach $export (@exports)
{
$name = $exportnames{$export};
$name = defined $name ? $name . " " : $dll . "_" . $export;

printf("%4d stub %s\n",$export,$name);

}




Re: why does wine use stdin, stdout & stderr streams from wineserver?

2000-08-17 Thread David Howells


> They could have been changed using SetStdHandle().
Not so.

> And the plain stdio stdin/stderr/stdout are not affected.
Again, apparently not so.

I compiled the following program up with MSDEV6 and ran it under wine:

#include 
int main()
{
printf("hello\n");
return 0;
}

The output of the program comes out of wineserver's stdout not wine's (I ran
wineserver in one xterm, and wine in another).

I checked to see if SetStdHandle() is called - it is not (at least, I ran wine
under gdb and set a breakpoint, which didn't trip).

David Howells




why does wine use stdin, stdout & stderr streams from wineserver?

2000-08-16 Thread David Howells


Can someone explain why wineserver passes it's UNIX stdin/out/err fd's to a
running wine program by socket-based FD transfer every time a wine application
wants to do an operation on it's idea of stdin/out/err?

This has some annoying effects:

* It's very difficult to redirect stdin/out/err on wine applications.

* The appropriate FD is passed _every_ time such an operation is issued (so if
  a lot of lines are being printed to stderr, say, a sendmsg/recvmsg pair is
  issued for every line).

* It costs a small fortune in context switches and message passing overhead.

To see what I mean, take a look at this "strace wine -- cl -?" excerpt...

write(3, "&\0\0\0", 4)  = 4
recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"\0\0\0\0", 4}], msg_controllen=16, 
msg_control=0x406f68a4, , msg_flags=0}, 0) = 4
write(6, "\r\n", 2) = 2
close(6)= 0
write(3, "&\0\0\0", 4)  = 4
recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"\0\0\0\0", 4}], msg_controllen=16, 
msg_control=0x406f68a4, , msg_flags=0}, 0) = 4
write(6, ""..., 44) = 44
close(6)= 0
write(3, "&\0\0\0", 4)  = 4
recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"\0\0\0\0", 4}], msg_controllen=16, 
msg_control=0x406f68a4, , msg_flags=0}, 0) = 4
write(6, "\r\n", 2) = 2
close(6)= 0
write(3, "&\0\0\0", 4)  = 4
recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"\0\0\0\0", 4}], msg_controllen=16, 
msg_control=0x406f68a0, , msg_flags=0}, 0) = 4
write(6, "(press  to continue)", 28) = 28
close(6)= 0

Every time it wants to write a line, it goes to wineserver (fd 3) and asks to
be sent a fd for stderr (fd 6).

David Howells




creating a new DLL .spec file

2000-08-16 Thread David Howells

I'd like to create a builtin DLL for cygwin, and I was wondering if there is a
script or program for autogenerating an initial spec file given a DLL to look
at.

I can see that it could be done, given that the objdump program from the
binutils-2.10.0 package running on Linux can be used to get at the import and
export tables from the DLL.

David Howells




Re: Windows system DLLs without Windows installation

2000-07-24 Thread David Howells


Hi Andreas,

Quick question for you (or anyone else who knows)...

How difficult would it be to emulate in software a PE DLL/EXE file with only a
resource section (no text, data or relocation sections), such that if wine
OpenFile opens a known wine elf-dll file or a builtin-dll, it then does an
effective cut'n'paste of the resource section from the wine-dll to an emulated
PE file?

I know its not a nice way to do things, but it would solve the problem of
handling both elf-dlls and builtin-dlls without having to compile up and keep
in sync stub PE DLLs.

David




Re: Windows system DLLs without Windows installation

2000-07-21 Thread David Howells


> I just want to make sure that programs that check for the presence
> of a DLL file by means of OpenFile() find what they want.
> And I think adding a small NE/PE header is good, too.
> But don't let this get out of hand...
> (sorry for not really explaining it before...)

Do many programs do that? I must admit I'm a bit suprised...

I had an idea of subverting OpenFile() to mask the contents of an ELF DLL by
pretending to return a PE header, but I'm not sure that that's a good idea.

> The GetFileVersion*() thing will have to wait a bit, as it will require
> massive support in the loader to figure out the loadorder correctly.
> But maybe I'll forget about the loadorder for the beginning and try to
> always parse the builtin DLL first and if that fails I branch to the old
> NE/PE parser.
> Of course that'll need a big FIXME "loadorder stuff missing" then ;-)

Yuk.

What about non-builtin elfdlls? Like libshell32.so.1.0... ELF parsing is
fairly straight forward, so you could divert the DLL parser from, say,
shell32.dll to libshell32.so where appropriate, and read the resource block
out of there. Of course, this'd be easier if the resources were contained in a
special section (called .rsrc probably) and padded out with the bits of fluff
that MSDEV's RC program puts in.

David




Re: Windows system DLLs without Windows installation

2000-07-21 Thread David Howells

Andreas Mohr wrote:
>> Out of interest, why do you want fake NE/PE DLLs? Is it because some programs
>> try to 'manually' parse the DLLs rather than using system routines?
>I thought that it's better to include a header (which would be small anyway)
>for these files instead of just "touch"ing them.
>
>And I previously thought of adding different VS_VERSION_INFO resources for
>different Windows versions to the fake DLLs.
>But this is not good, I think.
>...

This still doesn't tell me why you want to use NE/PE DLL stubs... Is it so
that you can find the resources easily? If so, would it be possible to tell
gcc to store the resources in a .rsrc section as MSDEV does, and then just
parse the ELF directly to find the resources. 

> How do we implement the reading of the VERSION_INFO ?
> ...
> And a GetFileVersionInfo*() normally happens directly before a LoadLibrary()
> anyway.
> Hmm, a question about that:
> If we do the LoadLibrary() in GetFileVersionInfo*() and do a FreeLibrary()
> at the end (usage count down to 0 again ! -> removal),

I don't think you can make GetFileVersionInfo*() do LoadLibrary() as this will
need to drag in and initialise _all_ the dependency libraries too, which could
take nearly forever. Plus, I'm sure you can do this on EXE files as well as
DLL files.

I'd have thought your better off writing a simplified NE/PE parser that just
locates the resource block and pulls the version info out of it.

If you do this, then you can also use it to implement the convenience
functions for getting other resources, such as string tables, and also
implement the functions to _change_ those resources.

Also if you do a NE/PE parser as I've suggested, why not make it able to
handle ELF files too? :-)

David




Re: Windows system DLLs without Windows installation

2000-07-21 Thread David Howells


Andreas Mohr wrote:
> Sure, that's what I'll be working on soon.
> However most probably that won't be libraries (.so), but rather completely
> new NE or PE "fake DLLs" with a complete header and version resources.

Will you then be building the wine code into these DLL files rather than into
real .so files?

And if not, will there be some mechanism by which if someone tries to
dynamically load one of these DLLs, it will dynamically load the real .so file
in addition or instead?

Out of interest, why do you want fake NE/PE DLLs? Is it because some programs
try to 'manually' parse the DLLs rather than using system routines?

David Howells




Windows system DLLs without Windows installation

2000-07-20 Thread David Howells


[Wine Weekly News]

> System DLLs
> 
> The Wine team has determined that it is necessary to create fake DLL files to
> trick many applications that check for file existence to determine whether a
> particular feature (such as Winsock and its TCP/IP networking) is
> available. If this is a problem for you, you can create empty files in the
> "system" directory to make the application think it's there, and Wine's
> built-in DLL will be loaded when the application actually asks for it.
> (Unfortunately, tools/wineinstall does not create such empty files itself.)
> 
> Applications sometimes also try to inspect the version resources from the
> physical files (for example, to determine the DirectX version). Empty files
> will not do in this case, it is rather necessary to install files with
> complete version resources. This problem is currently being worked on. In the
> meantime, you may still need to grab some real DLL files to fool these apps
> with.
> ...

Can you instead construct a system32 directory and populate it with symlinks
to appropriate wine DLL replacements, for example:

   ln -s /opt/wine/lib/libshell32.so /opt/wine/share/system32/shell32.dll

The people can dynamically load them for resources or code without wine having
to anything more special than check the magic number on the front of the DLL
to see what type it is.

David Howells