Charles Davis wrote:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Here's a new version of my patch that's slightly less complicated. I didn't get a response last time, so I'm sending it again. Please, someone review my patch. I won't send it to wine-patches until I know I have this right (yes, I am a bit of a perfectionist).
To reiterate what I said about this patch last time, this patch will implement the CDROM_GetInterfaceInfo() function on Mac OS, which allows clients to, among other things, get a SCSI address to do whatever with. (If this is over your head, you can stop reading now. :)
That sort of thing should most likely be integrated with the diskarbitration stuff in mountmgr.
Really? I guess I could do it that way. But then how are IOCTL_SCSI_GET_ADDRESS clients supposed to get the address?
Oops, forgot to reply all again.
Charles Davis cdavis@mymail.mines.edu writes:
Charles Davis wrote:
Alexandre Julliard wrote:
That sort of thing should most likely be integrated with the diskarbitration stuff in mountmgr.
Really? I guess I could do it that way. But then how are IOCTL_SCSI_GET_ADDRESS clients supposed to get the address?
With an ioctl to mountmgr. There is a bit of infrastructure work to do first to assign the correct device to the file descriptor.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Charles Davis wrote:
Alexandre Julliard wrote:
That sort of thing should most likely be integrated with the diskarbitration stuff in mountmgr.
Really? I guess I could do it that way. But then how are IOCTL_SCSI_GET_ADDRESS clients supposed to get the address?
With an ioctl to mountmgr.
Right. Silly me.
There is a bit of infrastructure work to do first to assign the correct device to the file descriptor.
Now I just need to figure out how to do that. I read the headers and source, and figured out a QUERY_UNIX_DRIVE won't work because it needs a drive letter, and NTDLL isn't supposed to know about drive letters. Maybe we can use the device name by doing something similar to get_parent_device(). But that only works on Mac OS. If we do this for Linux, too, we'll have to figure something else out. Maybe if we fstat() the FD and get its device number, we can use it to find the file system corresponding to it. Something like that could work on Mac OS, too, and there's similar code elsewhere in Wine (in ntdll itself, if I'm not mistaken). Maybe I could even hijack that code for this purpose instead of reinventing the wheel.
We might need to define a new mountmgr IOCTL to get the address--or will an existing IOCTL do? In any case, we'll then have to implement whatever IOCTL gets chosen in mountmgr.
Do you want the Linux implementation moved over to mountmgr, too, or is it fine the way it is?
Charles Davis cdavis@mymail.mines.edu writes:
Now I just need to figure out how to do that. I read the headers and source, and figured out a QUERY_UNIX_DRIVE won't work because it needs a drive letter, and NTDLL isn't supposed to know about drive letters. Maybe we can use the device name by doing something similar to get_parent_device(). But that only works on Mac OS. If we do this for Linux, too, we'll have to figure something else out. Maybe if we fstat() the FD and get its device number, we can use it to find the file system corresponding to it. Something like that could work on Mac OS, too, and there's similar code elsewhere in Wine (in ntdll itself, if I'm not mistaken). Maybe I could even hijack that code for this purpose instead of reinventing the wheel.
The way it needs to work is basically that opening the device would open an NT-style device instead of directly the Unix device. Then you have a handle that you can use with mountmgr, and mountmgr can give you an appropriate unix fd for calls that are performed on the client side.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Now I just need to figure out how to do that. I read the headers and source, and figured out a QUERY_UNIX_DRIVE won't work because it needs a drive letter, and NTDLL isn't supposed to know about drive letters. Maybe we can use the device name by doing something similar to get_parent_device(). But that only works on Mac OS. If we do this for Linux, too, we'll have to figure something else out. Maybe if we fstat() the FD and get its device number, we can use it to find the file system corresponding to it. Something like that could work on Mac OS, too, and there's similar code elsewhere in Wine (in ntdll itself, if I'm not mistaken). Maybe I could even hijack that code for this purpose instead of reinventing the wheel.
The way it needs to work is basically that opening the device would open an NT-style device instead of directly the Unix device. Then you have a handle that you can use with mountmgr, and mountmgr can give you an appropriate unix fd for calls that are performed on the client side.
Oh, I see. You mean I should open a handle to mountmgr with NtOpenFile(). That's what I thought. Now I just need to figure out the right IOCTL. Maybe I need to make one up. And I still don't know how to specify the correct device to mountmgr. (The answer is "depends on the IOCTL," so I need to answer the first question before I can answer this one.)
Another thing I don't quite understand: what good would an FD from the mountmgr device do? I looked at mountmgr, and I don't see any code for handing out FDs. No open()s, no sendmsg()s, no nothing. The only function I see in ntdll for this is server_get_unix_fd(), which is what we use to get the device FD from the NT CD-ROM device handle, and again I don't see how that will help. I mean, it's probably something like a socket or a pipe so all we can do is read and write it. (With sockets, we have some system IOCTLs, but they're all for controlling the socket itself.) And that's if there even is one. I looked at wineserver, and it looks like some file objects don't have to have real FDs behind them. Or did you have a different FD in mind, one I haven't thought of?
Oh, and you didn't answer my other question. But I have a feeling you aren't going to even see this part, let alone answer it anytime soon.
Chip
Charles Davis cdavis@mymail.mines.edu writes:
Oh, I see. You mean I should open a handle to mountmgr with NtOpenFile(). That's what I thought. Now I just need to figure out the right IOCTL. Maybe I need to make one up. And I still don't know how to specify the correct device to mountmgr. (The answer is "depends on the IOCTL," so I need to answer the first question before I can answer this one.)
There's no new ioctl here, just an open. That is essentially supported already.
Another thing I don't quite understand: what good would an FD from the mountmgr device do? I looked at mountmgr, and I don't see any code for handing out FDs. No open()s, no sendmsg()s, no nothing. The only function I see in ntdll for this is server_get_unix_fd(), which is what we use to get the device FD from the NT CD-ROM device handle, and again I don't see how that will help. I mean, it's probably something like a socket or a pipe so all we can do is read and write it. (With sockets, we have some system IOCTLs, but they're all for controlling the socket itself.) And that's if there even is one. I looked at wineserver, and it looks like some file objects don't have to have real FDs behind them. Or did you have a different FD in mind, one I haven't thought of?
There's no mechanism for this at the moment, that's why I said some infrastructure is needed. mountmgr should be asked to open the unix device corresponding to the NT device, and that fd should get back to the app somehow.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Oh, I see. You mean I should open a handle to mountmgr with NtOpenFile(). That's what I thought. Now I just need to figure out the right IOCTL. Maybe I need to make one up. And I still don't know how to specify the correct device to mountmgr. (The answer is "depends on the IOCTL," so I need to answer the first question before I can answer this one.)
There's no new ioctl here, just an open. That is essentially supported already.
Another thing I don't quite understand: what good would an FD from the mountmgr device do? I looked at mountmgr, and I don't see any code for handing out FDs. No open()s, no sendmsg()s, no nothing. The only function I see in ntdll for this is server_get_unix_fd(), which is what we use to get the device FD from the NT CD-ROM device handle, and again I don't see how that will help. I mean, it's probably something like a socket or a pipe so all we can do is read and write it. (With sockets, we have some system IOCTLs, but they're all for controlling the socket itself.) And that's if there even is one. I looked at wineserver, and it looks like some file objects don't have to have real FDs behind them. Or did you have a different FD in mind, one I haven't thought of?
There's no mechanism for this at the moment, that's why I said some infrastructure is needed. mountmgr should be asked to open the unix device corresponding to the NT device, and that fd should get back to the app somehow.
Oh, OK, I see what you're getting at. (Can't believe I didn't see it sooner...) I open mountmgr, then I ask it for the unix FD for the parent of the partition, corresponding to the NT device. You want me to move the process of getting the parent FD to mountmgr.
But then I have to get the FD back from mountmgr. For that, we need a UNIX domain socket. Mountmgr needs to know about it so it can send the FD using a control message (the way wineserver and ntdll exchange FDs).
But I still don't see how that allows me to find out the SCSI address of a CD-ROM drive.
Chip
Charles Davis wrote:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Oh, I see. You mean I should open a handle to mountmgr with NtOpenFile(). That's what I thought. Now I just need to figure out the right IOCTL. Maybe I need to make one up. And I still don't know how to specify the correct device to mountmgr. (The answer is "depends on the IOCTL," so I need to answer the first question before I can answer this one.)
There's no new ioctl here, just an open. That is essentially supported already.
Another thing I don't quite understand: what good would an FD from the mountmgr device do? I looked at mountmgr, and I don't see any code for handing out FDs. No open()s, no sendmsg()s, no nothing. The only function I see in ntdll for this is server_get_unix_fd(), which is what we use to get the device FD from the NT CD-ROM device handle, and again I don't see how that will help. I mean, it's probably something like a socket or a pipe so all we can do is read and write it. (With sockets, we have some system IOCTLs, but they're all for controlling the socket itself.) And that's if there even is one. I looked at wineserver, and it looks like some file objects don't have to have real FDs behind them. Or did you have a different FD in mind, one I haven't thought of?
There's no mechanism for this at the moment, that's why I said some infrastructure is needed. mountmgr should be asked to open the unix device corresponding to the NT device, and that fd should get back to the app somehow.
Oh, OK, I see what you're getting at. (Can't believe I didn't see it sooner...) I open mountmgr, then I ask it for the unix FD for the parent of the partition, corresponding to the NT device. You want me to move the process of getting the parent FD to mountmgr.
Or, maybe not. I could be totally wrong about that. Maybe what you really want is for me to get an FD from mountmgr so I can talk to it at will. I don't know.
We can even add the FD to mountmgr's run loop (via a CFFileDescriptor object), or if you prefer, we can do the traditional select() or poll() loop. (But why spawn another thread just for that?)
Charles Davis cdavis@mymail.mines.edu writes:
Or, maybe not. I could be totally wrong about that. Maybe what you really want is for me to get an FD from mountmgr so I can talk to it at will. I don't know.
We can even add the FD to mountmgr's run loop (via a CFFileDescriptor object), or if you prefer, we can do the traditional select() or poll() loop. (But why spawn another thread just for that?)
No, nothing of the kind. You wouldn't talk to mountmgr at all. All you would do is do an ioctl on an NT device, and that would magically get routed to the right place. Look at how IOCTL_STORAGE_GET_DEVICE_NUMBER is handled for a hard disk device for instance.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Or, maybe not. I could be totally wrong about that. Maybe what you really want is for me to get an FD from mountmgr so I can talk to it at will. I don't know.
We can even add the FD to mountmgr's run loop (via a CFFileDescriptor object), or if you prefer, we can do the traditional select() or poll() loop. (But why spawn another thread just for that?)
No, nothing of the kind. You wouldn't talk to mountmgr at all. All you would do is do an ioctl on an NT device, and that would magically get routed to the right place. Look at how IOCTL_STORAGE_GET_DEVICE_NUMBER is handled for a hard disk device for instance.
OK, now I'm thoroughly confused. What's the purpose of getting an FD from mountmgr in all this? And what the hell am I trying to do in the first place?! (Sorry for the language, but I just don't understand what you're getting at.)
Am I wasting your time? Because I've exchanged more correspondence with you over this than most people do over other issues.
Chip
Charles Davis cdavis@mymail.mines.edu writes:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Or, maybe not. I could be totally wrong about that. Maybe what you really want is for me to get an FD from mountmgr so I can talk to it at will. I don't know.
We can even add the FD to mountmgr's run loop (via a CFFileDescriptor object), or if you prefer, we can do the traditional select() or poll() loop. (But why spawn another thread just for that?)
No, nothing of the kind. You wouldn't talk to mountmgr at all. All you would do is do an ioctl on an NT device, and that would magically get routed to the right place. Look at how IOCTL_STORAGE_GET_DEVICE_NUMBER is handled for a hard disk device for instance.
OK, now I'm thoroughly confused. What's the purpose of getting an FD from mountmgr in all this? And what the hell am I trying to do in the first place?! (Sorry for the language, but I just don't understand what you're getting at.)
You don't need an fd for that specific ioctl, if you implement it in mountmgr. You need it for the other ones that are still done on the client side, and for normal I/O calls.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
Or, maybe not. I could be totally wrong about that. Maybe what you really want is for me to get an FD from mountmgr so I can talk to it at will. I don't know.
We can even add the FD to mountmgr's run loop (via a CFFileDescriptor object), or if you prefer, we can do the traditional select() or poll() loop. (But why spawn another thread just for that?)
No, nothing of the kind. You wouldn't talk to mountmgr at all. All you would do is do an ioctl on an NT device, and that would magically get routed to the right place. Look at how IOCTL_STORAGE_GET_DEVICE_NUMBER is handled for a hard disk device for instance.
OK, now I'm thoroughly confused. What's the purpose of getting an FD from mountmgr in all this? And what the hell am I trying to do in the first place?! (Sorry for the language, but I just don't understand what you're getting at.)
You don't need an fd for that specific ioctl, if you implement it in mountmgr. You need it for the other ones that are still done on the client side, and for normal I/O calls.
OK, so let me see if I have all this straight: you want me to implement some wine-specific IOCTLs in mountmgr that return the SCSI address and anything else I can think of tha belongs in mountmgr. You also say that, if necessary, I should pass an FD from mountmgr back to the caller (ntdll) via a UNIX-domain socket, but that I don't have to for this particular IOCTL. You also want me to move getting the parent device into mountmgr (where I think it belongs, frankly), which is an instance where I'd need to pass an FD back to ntdll. Do I have all this right?
Charles Davis cdavis@mymail.mines.edu writes:
OK, so let me see if I have all this straight: you want me to implement some wine-specific IOCTLs in mountmgr that return the SCSI address and anything else I can think of tha belongs in mountmgr. You also say that, if necessary, I should pass an FD from mountmgr back to the caller (ntdll) via a UNIX-domain socket, but that I don't have to for this particular IOCTL. You also want me to move getting the parent device into mountmgr (where I think it belongs, frankly), which is an instance where I'd need to pass an FD back to ntdll. Do I have all this right?
Not entirely right, no. First there wouldn't be wine-specific ioctl, it's just the standard Windows ioctls that would be implemented by the corresponding NT device. Second you wouldn't pass an fd back to ntdll, you'd pass it to the server, or have the server open the file.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
OK, so let me see if I have all this straight: you want me to implement some wine-specific IOCTLs in mountmgr that return the SCSI address and anything else I can think of tha belongs in mountmgr. You also say that, if necessary, I should pass an FD from mountmgr back to the caller (ntdll) via a UNIX-domain socket, but that I don't have to for this particular IOCTL. You also want me to move getting the parent device into mountmgr (where I think it belongs, frankly), which is an instance where I'd need to pass an FD back to ntdll. Do I have all this right?
Not entirely right, no. First there wouldn't be wine-specific ioctl, it's just the standard Windows ioctls that would be implemented by the corresponding NT device. Second you wouldn't pass an fd back to ntdll, you'd pass it to the server, or have the server open the file.
OK, thanks. Now I've got this straight. I should do something like dlls/mountmgr.sys/device.c, where I'd have an NT device like \Device\CdRom0 (or some such), whose FD I'd pass to the server so that when NTDLL opens the device and gets its FD, it still has the CD-ROM device for client-side calls. But when I need to call mountmgr, I open \Device\CdRom0 (or some such) and pass the IOCTL on to mountmgr. Is that right? Or am I still missing something?
Chip
Charles Davis cdavis@mymail.mines.edu writes:
OK, thanks. Now I've got this straight. I should do something like dlls/mountmgr.sys/device.c, where I'd have an NT device like \Device\CdRom0 (or some such), whose FD I'd pass to the server so that when NTDLL opens the device and gets its FD, it still has the CD-ROM device for client-side calls. But when I need to call mountmgr, I open \Device\CdRom0 (or some such) and pass the IOCTL on to mountmgr. Is that right? Or am I still missing something?
Pretty much, except of course you don't open \Device\CdRom0 yourself, the app does that, and you get a handle to it.
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
OK, thanks. Now I've got this straight. I should do something like dlls/mountmgr.sys/device.c, where I'd have an NT device like \Device\CdRom0 (or some such), whose FD I'd pass to the server so that when NTDLL opens the device and gets its FD, it still has the CD-ROM device for client-side calls. But when I need to call mountmgr, I open \Device\CdRom0 (or some such) and pass the IOCTL on to mountmgr. Is that right? Or am I still missing something?
Pretty much, except of course you don't open \Device\CdRom0 yourself, the app does that, and you get a handle to it.
OK. Actually, I thought of that right as I got your email. Now only one thing bothers me. Right now, ntdll does special-casing on DOS devices. So, if you open \DosDevices\D: with NtOpenFile() (or equivalently, \.\D: with kernel32.CreateFile), ntdll magically turns that into $WINEPREFIX/dosdevices/d::. Then the server opens the file like any UNIX file. What I'm guessing you want is for opens of \DosDevices\D: to go to \Device\CdRom0 (because \DosDevices\D: is supposed to be an NT symbolic link). How then am I supposed to associate a UNIX file with \Device\CdRom0? Or, is this not what you want?
Charles Davis wrote:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
OK, thanks. Now I've got this straight. I should do something like dlls/mountmgr.sys/device.c, where I'd have an NT device like \Device\CdRom0 (or some such), whose FD I'd pass to the server so that when NTDLL opens the device and gets its FD, it still has the CD-ROM device for client-side calls. But when I need to call mountmgr, I open \Device\CdRom0 (or some such) and pass the IOCTL on to mountmgr. Is that right? Or am I still missing something?
Pretty much, except of course you don't open \Device\CdRom0 yourself, the app does that, and you get a handle to it.
OK. Actually, I thought of that right as I got your email. Now only one thing bothers me. Right now, ntdll does special-casing on DOS devices. So, if you open \DosDevices\D: with NtOpenFile() (or equivalently, \.\D: with kernel32.CreateFile), ntdll magically turns that into $WINEPREFIX/dosdevices/d::. Then the server opens the file like any UNIX file. What I'm guessing you want is for opens of \DosDevices\D: to go to \Device\CdRom0 (because \DosDevices\D: is supposed to be an NT symbolic link). How then am I supposed to associate a UNIX file with \Device\CdRom0? Or, is this not what you want?
OK, I've done some research, and I've figured out that I need to handle IRP_MJ_CREATE in mountmgr. According to MSDN, this is the major function code for device open requests. But then how do I associate an FD to the file handle that gets created afterwards? And is calling the IRP_MJ_CREATE handler even implemented, or do I have to do that myself, too?
Charles Davis wrote:
Charles Davis wrote:
Alexandre Julliard wrote:
Charles Davis cdavis@mymail.mines.edu writes:
OK, thanks. Now I've got this straight. I should do something like dlls/mountmgr.sys/device.c, where I'd have an NT device like \Device\CdRom0 (or some such), whose FD I'd pass to the server so that when NTDLL opens the device and gets its FD, it still has the CD-ROM device for client-side calls. But when I need to call mountmgr, I open \Device\CdRom0 (or some such) and pass the IOCTL on to mountmgr. Is that right? Or am I still missing something?
Pretty much, except of course you don't open \Device\CdRom0 yourself, the app does that, and you get a handle to it.
OK. Actually, I thought of that right as I got your email. Now only one thing bothers me. Right now, ntdll does special-casing on DOS devices. So, if you open \DosDevices\D: with NtOpenFile() (or equivalently, \.\D: with kernel32.CreateFile), ntdll magically turns that into $WINEPREFIX/dosdevices/d::. Then the server opens the file like any UNIX file. What I'm guessing you want is for opens of \DosDevices\D: to go to \Device\CdRom0 (because \DosDevices\D: is supposed to be an NT symbolic link). How then am I supposed to associate a UNIX file with \Device\CdRom0? Or, is this not what you want?
OK, I've done some research, and I've figured out that I need to handle IRP_MJ_CREATE in mountmgr. According to MSDN, this is the major function code for device open requests. But then how do I associate an FD to the file handle that gets created afterwards? And is calling the IRP_MJ_CREATE handler even implemented, or do I have to do that myself, too?
I have another idea that, unlike my previous one, might actually work. What if the server kept track of which UNIX device files belonged to which device objects? Then, when the server gets a request to open a device, it could back the associated file object with a real FD object coming from the UNIX device. Mountmgr could call the server with the path to the UNIX device file it wants to associate to its device objects. Do you think that will work? IRP_MJ_CREATE doesn't seem to be implemented in ntoskrnl, so I'm going to assume that going the IRP_MJ_CREATE route won't work--or at least will require substantial work.
I've fixed most of the issues with my patch set (warnings, crashes, dangling FDs... yeah, I'll admit that last set of mine was a piece of crap; that'll teach me to send before testing), but I have one concern. After my patch series is applied, NtOpenFile() and NtCreateFile(), when handed a drive, should attempt to open the NT symlink ??<drive-letter>:. This should, in theory, cause an open of the corresponding NT device. But I've looked at server/symlink.c, and it looks like symlinks can't be opened as file-like objects (open_file implementation is no_open_file). So,, what happens when an NT symlink to a file-like object is opened with NtOpenFile()/NtCreateFile(), and is there anything I need to do to make this work?