Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shell extensions? #1041

Open
duckfromdiscord opened this issue Apr 16, 2023 · 17 comments
Open

Shell extensions? #1041

duckfromdiscord opened this issue Apr 16, 2023 · 17 comments

Comments

@duckfromdiscord
Copy link

This is my first time working w/ the Windows API so bear with me.

Is there a way to make a shell extension in winapi? I want to use IPropertyStore::SetValue to add info to the Details pane when you try to view a certain type of file's properties.

It looks like winapi isn't being maintained very much anymore but I thought I would ask.

@sollyucko
Copy link

What exactly are you asking? That function does exist: https://docs.rs/winapi/latest/winapi/um/propsys/struct.IPropertyStore.html#method.SetValue

@duckfromdiscord
Copy link
Author

What exactly are you asking? That function does exist: https://docs.rs/winapi/latest/winapi/um/propsys/struct.IPropertyStore.html#method.SetValue

@sollyucko Thank you for the quick response :) I'm asking how to make a shell extension that will register this function and allow me to call it. I think I have to make a dll and then register it. What I want to know is how to make that dll in Rust. Do I need to write a DllMain? Where do I go from there?

@duckfromdiscord
Copy link
Author

I will try to explain better. I want to create a shell extension, with just Rust, that will let me modify how Windows Explorer deals with reading details from a certain file type. But the issue is I don't know how to make something like that.

@sollyucko
Copy link

You can use crate-type=cdylib to generate a C-compatible DLL: https://doc.rust-lang.org/reference/linkage.html

@duckfromdiscord
Copy link
Author

Awesome :) now what functions do I add here to make it work with the shell? DllMain perhaps? And how do I implement the interface

@sollyucko
Copy link

Yeah, I guess so. I'm not very familiar with this, but I think these resources should help you get started:

@duckfromdiscord
Copy link
Author

This is good. Thank you. I'll let you know how it goes

@duckfromdiscord
Copy link
Author

@sollyucko
Copy link

I'm not sure. Maybe use RIDL! somehow?

@duckfromdiscord
Copy link
Author

I'm gonna use https://raw.githubusercontent.com/GabrielMajeri/com-impl-rs for now. So I have to Rewrite-it-in-Rust for everything in that example you sent?

@duckfromdiscord
Copy link
Author

I've started to remake all of it. I'm not sure it'll work because the macro doesn't tell me whether I'm using the correct function signatures or not. I may miss a *mut or a * or a ** somewhere.

@duckfromdiscord
Copy link
Author

I will post my progress at https://github.com/duckfromdiscord/midi-windows-ext periodically.

for RegCreateKeyExW, if phkResult is an out, why does it ask me to initialize it?

error[E0381]: used binding `hKey` isn't initialized
  --> src\reg.rs:28:47
   |
20 |     let mut hKey: *mut HKEY;
   |         -------- binding declared here but left uninitialized
...
28 |          KEY_WRITE, &mut security_attributes, hKey, 0 as *mut u32).try_into().unwrap());
   |                                               ^^^^ `hKey` used here but it isn't initialized
   |
help: consider assigning a value
   |
20 |     let mut hKey: *mut HKEY = todo!();
   |    

@sollyucko
Copy link

So I have to Rewrite-it-in-Rust for everything in that example you sent?

Yeah, probably, unless you want to deal with C++ FFI.

I may miss a *mut or a * or a ** somewhere.

Just keep in mind that P or LP means *mut and PC or LPC means *const, and you should be fine, I think.

for RegCreateKeyExW, if phkResult is an out, why does it ask me to initialize it?

You're trying to directly read the value of an uninitialized variable. Assuming you're trying to have the handle end up directly in hKey, not in what in points to, do one of the following:

@duckfromdiscord
Copy link
Author

Thank you very much.

@duckfromdiscord
Copy link
Author

duckfromdiscord commented Apr 18, 2023

We don't have StringCchPrintf

@sollyucko
Copy link

winapi does have w(v)sprintf(A/W); can you use that instead? The buffer has a fixed length of 1024 bytes though...

libc::snprintf is probably a much better option.

format!/write! is another option, but that has different format string syntax and output semantics.

I think the String... functions are only defined in strsafe.h, not in any built-in object files, but you could write a bit of C code to generate an object file with them, then write custom bindings to link it to your Rust code.

@duckfromdiscord
Copy link
Author

Yeah, I guess so. I'm not very familiar with this, but I think these resources should help you get started:

* Well-commented example C++ source code: https://www.tecgraf.puc-rio.br/iup/examples/shell_extensions/ (start with dllmain.cpp)

* "Initializing Shell Extension Handlers": https://learn.microsoft.com/en-us/windows/win32/shell/int-shell-exts

Looks like somehow, between the last time I was looking at this code 3 weeks ago, and today, they privated all the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants