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:
155763 How To Call 16-bit Code from 32-bit Code Under Windows 95
NOTE: The Windows for Workgroups SDK is no longer available for purchase from Microsoft and is not supported after Nov. 30, 2001. Customers who want functionality that is only provided by the Windows for Workgroups SDK should contact Microsoft Developer Support to obtain the necessary header and library files:
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:
180548 How To Validate User Credentials on Microsoft Operating Systems
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;
}