HOWTO: Programmatically Log On to a Network on Win95/Win98

ID: Q197236


The information in this article applies to:


SUMMARY

On Windows 95 or Windows 98, programs can call the 16-bit LAN Manager API NetWkstaSetUID2() to log on and log off a network.


MORE INFORMATION

When a user presses the Cancel button or the ESC key at the Enter Network Password dialog box, the system logs the user on as a local non-authenticated user. This allows the user to work locally without any network access. To access the network from this state, the user must log off and then log on again from the three-tiered Enter Network Password dialog box.

To avoid making a user log off and log on again, the 16-bit LAN Manager function NetWkstaSetUID2() can be called to obtain access to a network. The NetWkstaSetUID2() API can be imported from NetAPI.lib, which is available in the Windows for Workgroups SDK. This 16-bit function can be called from 16-bit applications. To call this function from 32-bit applications, please see the following article in the Microsoft Knowledge Base:

Q155763 HOWTO: Call 16-bit Code from 32-bit Code Under Windows 95
Please see www.microsoft.com for information on obtaining the Windows for Workgroups SDK.

NetWkstaSetUID2() should not be used to authenticate user credentials. The API performs a full logon, which modifies the state of the system. For information on authentication, please see the following article in the Microsoft Knowledge Base:

Q180548 HOWTO: Validate User Credentials on Microsoft WinNT and Win95
On Windows 95, after calling the NetWkstaSetUID2() API to log on to the network, the NetWkStaSetUID2() API must be called again to log off from the network before the system attempts to log off locally. To do this, the process calling NetWkstaSetUID2() can create a hidden top-level window that will stay resident for the duration of the logged on session. When the user logs off, the system sends a WM_ENDSESSION message to all top-level windows. Upon receiving this WM_ENDSESSION message, the process needs to call NetWkstaSetUID2() to log off from the network. This ensures that the user is logged off from the network before the system attempts to log off locally. On Windows 98 this procedure is not needed.

The following code demonstrates the use of NetWkstaSetUID2() to log on and log off of Windows 95 and Windows 98. This is a 16-bit Windows application that must be compiled using a 16-bit compiler:

/*++

      Copyright (c) 1998  Microsoft Corporation

      Module Name:

         Logon.c

      Description:

         Demonstrates use of NetWkStaSetUID2 API to log on and
       log off of Windows 95 or Windows 98

         The following import libraries are required:
         NetAPI.lib

   --*/ 
   #define INCL_NETWKSTA
   #define INCL_NETERRORS

   #include <windows.h>
   #include <lan.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <ctype.h>
 
   #define BUFFSIZE 1000
 
   char buffer[BUFFSIZE];


   void Usage()
   {
      MessageBox(NULL,"Usage: Logon <UserName> <Domain> <password>",
                                                      "Input Error",MB_OK);
   
      exit(1);
   }

   void FatalMessage(LPSTR szMessage)
   {
      MessageBox(NULL,szMessage,"Error",MB_OK);
      exit(1);
   }

   int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdLine, int nCmdShow)    
   {
      char     lpszNewCmdLine[256];
      char     szMsg[512];
      char far *  lpszdomain;
      char far *  lpszusername;
      char far *  lpszpass;
      char far *  argv[3];
      int      i = 0;
      int      argc = 1;
      int      res  = 0;
      unsigned short ta;
      struct user_logon_info_1  *pUsrLogon  
                           = (struct user_logon_info_1 *)  &buffer;
      struct user_logoff_info_1 *pUsrLogoff
                           = (struct user_logoff_info_1 *) &buffer;
   

      // Copy cmdline to a string you can modify then convert the
      // new string to uppercase. NetWkStaSetUID2 requires that
      // the user name password and domain name are converted to
      // uppercase. This does not mean Windows NT passwords must be 
      // uppercase. Windows NT domains that support LAN Manager logons
      // maintain a separate uppercase version of the Windows NT password 
      // for logging on from Windows 3.x, Windows 95, and Windows 98 
      // machines.
   
      lstrcpy(lpszNewCmdLine,lpszCmdLine);
   
      while (TRUE)
      { 
         if (lpszNewCmdLine[i] == '\0')
            break;

         lpszNewCmdLine[i] = (char)toupper(lpszNewCmdLine[i]);
         i++;
      }


      // Set argv pointers: argv[0] is the first parameter because
      // the .exe name is not in lpszCmdline.
   
      argv[0] = (char far *)lpszNewCmdLine;
               
      for (i=1;i>0;i++)
      {   
         if (lpszNewCmdLine[i] == '\0')
         break;
         if (lpszNewCmdLine[i] == ' ')
         { 
             lpszNewCmdLine[i] = '\0';
             //  The Previous argc is the new argv index; so use it, then include it.
            argv[argc++] = (char far *) &(lpszNewCmdLine[i+1]);
            if (argc > 3)
               Usage();
         }   
      }

      if (argc != 3) Usage();
   
      lpszusername = argv[0];
      lpszdomain = argv[1];
      lpszpass = argv[2];

   
      res=NetWkstaSetUID2((char far *)NULL,
                     (char far *)lpszdomain,
                     (char far *)lpszusername,
                     (char far *)lpszpass,
                     (char far *)"",
                     0,
                     1,
                     (char far *) buffer,
                     sizeof(buffer),
                     (unsigned short far *) &ta);
               
      if((res != NERR_Success) && 
         (res != NERR_UnableToAddName_W))
      {
         NetWkstaSetUID2(NULL, NULL, NULL, NULL, NULL, 3, 1,
                         (char far *) &buffer, sizeof(buffer), &ta);
         wsprintf(szMsg,"Logon Error: %u", res);
           FatalMessage(szMsg);
      }
   
      else
      {
         switch(pUsrLogon->usrlog1_code)
         {
         case NERR_Success:
            wsprintf( (LPSTR)szMsg,"Logon successful. Return code: %u\n"
                              "Press Ok to logoff",
                                       pUsrLogon->usrlog1_code);
            MessageBox(NULL, szMsg, "Success", MB_OK);  
            break;
         default:
            /* See NETERR.H for details on return codes */  
            NetWkstaSetUID2(NULL, NULL, NULL, NULL, NULL, 3, 1,
                            (char far *) &buffer, sizeof(buffer), &ta);
            wsprintf(szMsg, "Logon Error. Return code: %u\n", res);
            FatalMessage(szMsg);
         }
      } 

      res = NetWkstaSetUID2(NULL, NULL, NULL, NULL, NULL, 3, 1,
                            (char far *) &buffer, sizeof(buffer), &ta);
      if((res != NERR_Success) && (res != NERR_UnableToDelName_W))
      {
         wsprintf(szMsg,"Error on logoff: %u\n", res);
         FatalMessage(szMsg);
      }
      else
      {
         wsprintf(szMsg, "Logoff successful.\n");
         MessageBox(NULL, szMsg, "Success", MB_OK);
      }
      return 0;
   } 


REFERENCES

For additional information, please see the following article in the Microsoft Knowledge Base:

Q155763 HOWTO: Call 16-bit Code from 32-bit Code Under Windows 95
For information on obtaining the Windows for Workgroups SDK, please connect to the following Web site:

www.microsoft.com

Additional query words:


Keywords          : kbnetwork kbKernBase kbSecurity 
Version           : winnt:
Platform          : winnt 
Issue type        : kbhowto 

Last Reviewed: January 27, 1999