2

This is my first question.

I would like to know if there is a way to set a button on the login screen to open a custom app.

I have already searched by Microsoft documentation then found about credential provider but I don't want to create an IU login. I just want to open an application like this:

enter image description here

enter image description here

This is what I want to achieve

If there is something that might help me it will be welcome.

Bob White
  • 733
  • 5
  • 20
  • Looks like you can find a demo version of that software. Use a registry snapshot tool and find out where that program registers itself. – Anders Sep 25 '19 at 18:38
  • the website for a demo is down. – Bob White Sep 25 '19 at 18:53
  • I guess the use the method HRESULT PasswordResetCredential::SetSelected(BOOL* pbAutoLogon) to launch the app – Bob White Sep 25 '19 at 18:55
  • 3
    It might not actually be an application, the UI could all be part of the credential provider - that's the way it *ought* to be done, at any rate. But I believe if you launch an application from a credential provider (via CreateProcess or by any other means) it will be visible to the user. – Harry Johnston Sep 27 '19 at 01:25
  • 1
    In Provider::SetUsageScenario, enumerate your credential under CPUS_LOGON case. Increment pdwCount in GetCredentialCount to set number of tiles to display. Enumerate the credential in getCredentialAt. What you do in that credential doesn't matter. As @Harry_Johnston said, you can pretty much load any graphical interface (Windows Login screen simply being a desktop particularly locked down to lambda users). Do your stuff in it then call for CredentialsChanged event to get back to Tile selection screen. - Had to pass the details like tile picture load etc... due to comment size restriction. – Kianii Sep 27 '19 at 09:08
  • Almost everything is set up as you request. I following this https://blogs.technet.microsoft.com/aho/2009/11/14/custom-credential-provider-for-password-reset/ I don't know where open the app and hide all the IU. what I need is just click on the tile then open the app. – Bob White Sep 27 '19 at 14:51
  • I'd do it in Credential::SetSelected as you mentionned. I never worked with a "classic behavior" credential though... so make sure there is no problems with loading your interface BEFORE returning S_OK. Might be completely transparent... specially if your IU hide tiles. – Kianii Sep 27 '19 at 15:29
  • you can see where I call my app https://github.com/azufre/CredentialProvider/blob/8697c8b1b95f6c43853a85dbf803b6d64dcdbcc4/PasswordResetCredentialProvider/PasswordResetCredential.cpp#L132 it works. but when it is selected the tile and get block the screen after a few minutes it open by itself the app. – Bob White Sep 27 '19 at 16:02
  • system(start) doesn't pause the current thread that keeps going & returns S_OK. What you wanna do is to not return while your app is running. And even this might not give you the expected result. In the case your credential formally want you to return, you'd have to launch the App thread before the function and use SetEvent/WaitForSingleObject to decide wether or not the UI should be displayed. – Kianii Sep 27 '19 at 16:29
  • I don't want to display the IU. what method should I use? – Bob White Sep 27 '19 at 16:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200078/discussion-between-bob-white-and-kianii). – Bob White Sep 27 '19 at 17:52
  • 1
    What they seem to be doing in the initial example you gave us is just displaying some kind of user interface so that it hides the logon screen. In your case, the program is totally isolated from the credential code. – Kianii Sep 30 '19 at 09:24
  • Yep I want to get that. I ask for that. – Bob White Sep 30 '19 at 13:58
  • Using system(start), they probably don't share the same adress space. I don't think there is anything you can do about it. Except inside TestStartApp.exe code. Depends what it is written with. – Kianii Sep 30 '19 at 15:45
  • yep, I did it. but there is something more to face. I got opened the app but if the screen gets the background lock the app is launched, it's like the event Credential::SetSelected is triggered by default. – Bob White Sep 30 '19 at 16:45
  • Do we agree that the code given below didn't change. Especially the following : Credential::SetSelected --> *pbAutoLogon still set to FALSE Provider::GetCredentialCount --> *pdwDefault still set on CREDENTIAL_PROVIDER_NO_DEFAULT & *pbAutoLogonWithDefault to FALSE Provider::GetCredentialAt didn't change too much. – Kianii Oct 01 '19 at 09:14

2 Answers2

4

To open a custom app by using credentials provider there are two ways to do it.

1) Launch an app when trigger the event SetSelected from provider credential

HRESULT PasswordResetCredential::SetSelected(BOOL* pbAutoLogon)  
{
    *pbAutoLogon = FALSE;  

    system("start C:\\TestStartApp.exe");

    return S_OK;
}

It may work fine but when the screen gets the wallpaper lock it will trigger automatically the event SetSelected. so the app will reopen again.

2) Create an CommanLink then launch the app in the event CommandLinkClicked

HRESULT PasswordResetCredential::CommandLinkClicked(DWORD dwFieldID)
{

    HRESULT hr = S_OK;

    if (dwFieldID < ARRAYSIZE(_rgCredProvFieldDescriptors) && (CPFT_COMMAND_LINK == _rgCredProvFieldDescriptors[dwFieldID].cpft)) {
        system("start C:\\TestStartApp.exe");
    }

    return hr;

}

both works but it could be a huge risk for our security. majority of developers doesn't recommend to use the credential provider for this way. we are using a fake credential provider to open an app.

Bob White
  • 733
  • 5
  • 20
0

To implement a call for expternal process inside of your own credential provider tile you must do this steps:

  1. Is call to ICredentialProviderCredential::Advise - your provider will receive a pointer to ICredentialProviderCredentialEvents interface of LogonUI.

  2. You call to ICredentialProviderCredentialEvents::OnCreatingWindow to obtain a HWND for parent window.

  3. As you mentioned above you can create a new process inside of handler to call of your providers ICredentialProviderCredential::SetSelected.

Have a look at this post.

Alexander
  • 1,232
  • 1
  • 15
  • 24