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

Add wincred.h #70

Closed
hpoul opened this issue Jul 13, 2020 · 10 comments · Fixed by #75
Closed

Add wincred.h #70

hpoul opened this issue Jul 13, 2020 · 10 comments · Fixed by #75
Labels
enhancement New feature or request help wanted Good candidate for others to work on

Comments

@hpoul
Copy link
Contributor

hpoul commented Jul 13, 2020

I am interested in using wincred.h: https://docs.microsoft.com/en-us/windows/win32/api/wincred/nf-wincred-credwritea
to port my plugin to windows.

Do you have any plans to add support for it - or how much work is it? I'm not completely sure how much magic is autogenerated and what has to be manually added :-)

@domesticmouse
Copy link
Collaborator

Hey @hpoul,

I think you will find @timsneath's answer in #64 (comment) helpful on the autogeneration / hand coding front.

Do you have an idea of which specific API calls you want to make?

@hpoul
Copy link
Contributor Author

hpoul commented Jul 13, 2020

@domesticmouse thanks for your fast reply, i think right now it's CredWrite, CredRead, CredDelete. I don't have experience with win32 APIs (yet), but those seem to be the closest to keychain read/write/delete :)

not sure if it's better to have a generic ffi bridge, or just use the specific C functions in my library (which is how i've implemented it for linux right now), but if it's easier to build on this package, it would be great ;-)

@timsneath
Copy link
Contributor

Yeah, easy enough to add those functions, and they seem useful to others also. I'll put a quick pull request together.

As far as the latter question is concerned, you're obviously welcome to do what works best for you. But three reasons why you might consider a direct dependency on win32:

  • With Dart tree shaking, you're not paying any additional 'tax' for the parts of win32 you're not using; only those typedefs that you actually use are compiled into your plugin;
  • Obviously any improvements made to the Win32 package come for free (e.g. Dart finalizer support, or improvements to struct layout, when they arrive)
  • If you ever choose to expose any of the credentials outside of your own package, it might be helpful if the Structs etc. are in a common package.

@hpoul
Copy link
Contributor Author

hpoul commented Jul 13, 2020

cool thanks, that would be great.

To be honest my question was actually if it would be easier for me to work out how to add those APIs to win32 and make a PR vs. just doing it in my own plugin. If I just have to use the package, I'll certainly go for it 😅️

@timsneath timsneath added enhancement New feature or request help wanted Good candidate for others to work on labels Jul 13, 2020
@timsneath
Copy link
Contributor

You are very welcome to do so, if you want to get familiar with these APIs. A couple of tips:

If you don't feel comfortable with doing this work, let me know; happy to investigate it at some point.

@domesticmouse
Copy link
Collaborator

domesticmouse commented Jul 15, 2020

@timsneath Can we promote your comment to a section in either the README? Seems like a useful getting started guide.

@timsneath
Copy link
Contributor

@hpoul
Copy link
Contributor Author

hpoul commented Jul 16, 2020

Thanks for the hints.. I've started adding the functions/structs and CredWrite seems to work as I can see the written credential in the Credential Manager, but CredRead returns success without filling my credential struct.
Do you have any idea what I could be doing wrong? I allocate a Pointer and pass it into the function, do I need to do something else to pass it by reference?

https://github.com/authpass/win32/blob/wincred/example/credentials.dart#L35-L43

  final cred = CREDENTIAL.allocate();
  final result = CredRead(
      TEXT(credentialName), CRED_TYPE_GENERIC, 0, cred.addressOf);
  if (result != TRUE) {
    final errorCode = GetLastError();
    print('Error ($result): $errorCode');
    return;
  }
  print('Success. size: ${cred.CredentialBlobSize}');

outputs:

Success. size: 0

(Even though I've written 10 bytes, which I can see in the Credential Manager)

@hpoul
Copy link
Contributor Author

hpoul commented Jul 16, 2020

never mind, I somehow missed that it was PCREDENTIAL not CREDENTIAL. 🤦️ ie. I had to use Pointer<Pointer<CREDENTIAL>>

@timsneath
Copy link
Contributor

Ah yes -- they're sneaky with that. The second * is masked in the typedef, so PCREDENTIAL *x is equivalent to CREDENTIAL **x. I spent days blocked on a similar issue when I built out the COM support, so the fact that you'd figured it out before I'd even looked at the code is something you can feel good about :)

@timsneath timsneath linked a pull request Jul 17, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Good candidate for others to work on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants