Microsoft KB Archive/197236

{|
 * width="100%"|

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

 * }

Q197236

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * Microsoft Windows 98
 * Microsoft Windows 95

-

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   #include    #include    #include    #include    #define BUFFSIZE 1000 char buffer[BUFFSIZE];

void Usage {     MessageBox(NULL,"Usage: Logon   ",                                                      "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; }