rodrigocfd / winsafe

Windows API and GUI in safe, idiomatic Rust.
https://crates.io/crates/winsafe
MIT License
518 stars 30 forks source link

winsvc.h #99

Closed TomzBench closed 1 year ago

TomzBench commented 1 year ago

This is more of discussion or feature request. But is there any interest in implementing the winsrv.h stuff like StartServiceCtrlDispatcher and associalted api's?

I find I am trying to implement wrappers around the winsrv api's from windows crate and thought perhaps forking winsafe and implementing them in here. the winsrv api's use a lot of types in the winuser.h. So I'm guessing all the consts and structs could be added to the user/co/consts and user/structs types and maybe add a new feature folder for service apis in winsrv.h?

is this correct way to go? Is this kind of PR welcome?

rodrigocfd commented 1 year ago

Hi Tom,

This is more of discussion or feature request. But is there any interest in implementing the winsrv.h stuff like StartServiceCtrlDispatcher and associalted api's?

Yes, I think it would be a nice addition to the library.

I find I am trying to implement wrappers around the winsrv api's from windows crate

That's pretty much how winsafe itself started: as safe wrapper to the good ol' winapi – the windows crate didn't even exist back in those days. Eventually winsafe evolved to completely remove winapi as a dependency, which made a lot of things easier and also boosted the compilation time (winsafe has zero dependencies).

and thought perhaps forking winsafe and implementing them in here.

Seems like a good idea. I would be glad to help you with your fork, until it's stable enough to be merged into the master branch.

the winsrv api's use a lot of types in the winuser.h. So I'm guessing all the consts and structs could be added to the user/co/consts and user/structs types and maybe add a new feature folder for service apis in winsrv.h?

The Cargo features of winsafe are based on the DLLs (kernel32, user32, etc.), and not on the C headers. But there is a very complicated story besides that...

My first attempt was very rigid about the Cargo features, with each item correctly placed according to its DLL. It was beautiful, a super organized library. But I quickly got a lot of headaches with the Windows API C headers. For example: the base of everything is kernel32; advapi32 is built on top of it. SECURITY_DESCRIPTOR is a struct which is used by many kernel32 calls, however, it is initialized via InitializeSecurityDescriptor which belongs to... advapi32. Yes, a circular dependency. And just one of many. I had no choice other than aglutinate advapi32 into kernel32 – you can read this note in the project README. And there are circular dependencies all over the place... it's unbelievable how careless those people were.

That said, let's dive onto your case.

As far as I could see, the winsrv.h functions belong to advapi32, which would place them into the kernel Cargo feature within winsafe. But you're telling me that they use constants and structs from user, which seems to be... another case of circular dependency. We would have to carefully evaluate each case, to see if we should downgrade the item from user to kernel, or upgrade the function from kernel to user.

Dealing with stuff like this can be pretty overwhelming, so I suggest you to start simple. Start with the first function call you need, then perform a Cargo check in isolation:

cargo check --features kernel

The proceed to the next function, until something weird appears.

And let me know of your progress, we can work together on this.

TomzBench commented 1 year ago

Hello @rodrigocfd

I sent a very preliminary PR here: https://github.com/rodrigocfd/winsafe/pull/100 which is not ready to merge at all but thought it would be useful so you can view it a bit.

After your helpful response and studying the Windows API more I see that the API's for working with Windows Services are similar to working with regular Windows. There is a lot of messaging and the messages are implemented in the user feature, and the API's for managing services are in the kernel feature. So I dont know if there is a circular dependency yet however I thought for first attemp I would just implement the service messaging types first. And then later add the kernel stuff.

The winsafe crate has a precedent for everything I needed to do so far, and so I tried my best to follow existing patterns. Let me know what you think and I'll finish adding the messaging types and service api's and comment again if stuck.