none
Non-zero error after a succesful API call in C# RRS feed

  • Question

  •  

    Hi folks

    I am calling the Windows API, LogonUser method to validate my users. During testing of this I notice that LogonUser was returning true (tres bon).

    Then I called Marshal.GetLastWin32Error() on the very next line and got error code 203.

    I am at a lost as to why this error code is been returned.

    I could "if" the LogonUser call and not worry about the error if it the return is true, but I don't like unexplained errors.

    Clues any one?

    Here is the API declaration:

     

     public static class externAPI
      {
        [DllImport("ADVAPI32.DLL", SetLastError=true)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out int phToken);
      }

     

    Here is my method:

    private static void logonUser(string domainName,string login,string password)
        {      
          int token = 0;
          bool res = externAPI.LogonUser(login, domainName, password, 3, 3, out token);
          Exception ex = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());     
        }

    BTW, there seems to be some confusion about the 4 and 5 arguments on LogonUser.     WinBase.h declares them as:

    #define LOGON32_LOGON_INTERACTIVE    2
    #define LOGON32_LOGON_NETWORK      3
    #define LOGON32_LOGON_BATCH       4
    #define LOGON32_LOGON_SERVICE      5
    #define LOGON32_LOGON_UNLOCK      7
    #if(_WIN32_WINNT >= 0x0500)
    #define LOGON32_LOGON_NETWORK_CLEARTEXT 8
    #define LOGON32_LOGON_NEW_CREDENTIALS  9
    #endif // (_WIN32_WINNT >= 0x0500)
    
    #define LOGON32_PROVIDER_DEFAULT  0
    #define LOGON32_PROVIDER_WINNT35  1
    #if(_WIN32_WINNT >= 0x0400)
    #define LOGON32_PROVIDER_WINNT40  2
    #endif /* _WIN32_WINNT >= 0x0400 */
    #if(_WIN32_WINNT >= 0x0500)
    #define LOGON32_PROVIDER_WINNT50  3
    #endif // (_WIN32_WINNT >= 0x0500)


    Other posts say

    LOGON32_LOGON_NETWORK_CLEARTEXT = 3


    I don't know which is correct, but it doesn't change the result of my test.

     

    regards

    GregJF

    • Edited by GregJF Wednesday, December 8, 2010 8:04 AM re-formated code
    Wednesday, December 8, 2010 7:56 AM

Answers

  • Hi GregJF,

     

    You're right, my test result shows that if LogonUser returns true, Marshal.GetLastWin32Error returns 0 to me, even though the function returns non-zero before invoking LoginUser.

     

                int token = 0;

     

                Console.WriteLine("before: " + Marshal.GetLastWin32Error());

                if (LogonUser(userName, domain, pwd, 3, 3, out token))

                {

                    Console.WriteLine("return true: " + Marshal.GetLastWin32Error());

                }

                else

                {

                    Console.WriteLine("return false: " + Marshal.GetLastWin32Error());

                }

                Console.WriteLine("after: " + Marshal.GetLastWin32Error());

     

                Console.ReadLine();

    The error code 203 means ERROR_ENVVAR_NOT_FOUND: “The system could not find the environment option that was entered”, so the failure may caused by the environment settings, you can try your code snippet in another machine.

    You may also create a C++ application in which you invoke the LogonUser function to see whether GetLastError returns non-zero.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Wednesday, December 22, 2010 5:08 AM
    Monday, December 13, 2010 3:02 AM
  • Hi,

    You can invoke the function from pure C++ code, if the same error code returns, you may try   General Windows Development forum for further support.

    Please feel free to let us know if you have any concern.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Wednesday, December 22, 2010 5:06 AM
    Thursday, December 16, 2010 10:01 AM

All replies

  •  

    Hi GregJF,

     

    As it is documented for LogonUser function:

     

    If the function succeeds, the function returns nonzero.

    If the function fails, it returns zero. To get extended error information, call GetLastError.

     

    If the function returns nonzero, we no need to care about the error code returned by GetLastError function, since last-error code is maintained on a per-thread basis, the error code may set by other functions.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, December 9, 2010 8:26 AM
  • Hi GregJF...first thing which i want to suggest u is that don't write unsafe code.unsafe code i mean to say with out handling the exceptions.if u could have written the same code inside the try catch block it would have been more easy instead of making a call to
    Marshal.GetLastWin32Error()

    Now regarding your probelm..you plz check it at the sql level if u have
    written some stored procedure for it by running the sql profiler..i hope it could
    solve ur problem






    Software Engineer
    Thursday, December 9, 2010 3:14 PM
  • eryang

    That may be what the MSDN doco says, but the function explicitly returns a BOOL, not a number!

    So are you saying that we just ignore the error message if a "True" is returned?

    BTW, I have created a test project that has only this call in it ie there are no other functions running in .net. Nor are there any other threads running.

    So how can I safely implement this?

     

    Regards

     

    GregJF

    Sunday, December 12, 2010 9:48 PM
  • Syed

    This is test code, made up to illustrate the point.

    I have created a test project that has only this call in it ie there are no other functions running in .net. Nor are there any other threads running. No calls to SQL or anything else!

     

    regards

     

    GregJF

    Sunday, December 12, 2010 9:50 PM
  • Hi GregJF,

     

    You're right, my test result shows that if LogonUser returns true, Marshal.GetLastWin32Error returns 0 to me, even though the function returns non-zero before invoking LoginUser.

     

                int token = 0;

     

                Console.WriteLine("before: " + Marshal.GetLastWin32Error());

                if (LogonUser(userName, domain, pwd, 3, 3, out token))

                {

                    Console.WriteLine("return true: " + Marshal.GetLastWin32Error());

                }

                else

                {

                    Console.WriteLine("return false: " + Marshal.GetLastWin32Error());

                }

                Console.WriteLine("after: " + Marshal.GetLastWin32Error());

     

                Console.ReadLine();

    The error code 203 means ERROR_ENVVAR_NOT_FOUND: “The system could not find the environment option that was entered”, so the failure may caused by the environment settings, you can try your code snippet in another machine.

    You may also create a C++ application in which you invoke the LogonUser function to see whether GetLastError returns non-zero.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Wednesday, December 22, 2010 5:08 AM
    Monday, December 13, 2010 3:02 AM
  • Eric

    I will try that.

    That error is the exact error I am getting.

    Anybody got a clue as to how to find what environment setting is causing the failure?

     

    regards

     

    GregJF

    Monday, December 13, 2010 11:34 PM
  • Hi,

    You can invoke the function from pure C++ code, if the same error code returns, you may try   General Windows Development forum for further support.

    Please feel free to let us know if you have any concern.


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by eryang Wednesday, December 22, 2010 5:06 AM
    Thursday, December 16, 2010 10:01 AM