NT4/private/nw/convert/nwconv/netutil.c
2020-09-30 17:12:29 +02:00

438 lines
13 KiB
C

/*
+-------------------------------------------------------------------------+
| Network Utility Functions |
+-------------------------------------------------------------------------+
| (c) Copyright 1993-1994 |
| Microsoft Corp. |
| All rights reserved |
| |
| Program : [NetUtil.c] |
| Programmer : Arthur Hanson |
| Original Program Date : [Feb 16, 1993] |
| Last Update : [Jun 16, 1994] |
| |
| Version: 1.00 |
| |
| Description: |
| |
| History: |
| arth Jun 16, 1994 1.00 Original Version. |
| |
+-------------------------------------------------------------------------+
*/
#include "globals.h"
#include "netutil.h"
static LPTSTR ServName;
static TCHAR szPassword[PWLEN+1];
static TCHAR szUserName[MAX_USER_NAME_LEN + 1];
LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL BadPassword;
/*+-------------------------------------------------------------------------+
| FixPathSlash()
|
+-------------------------------------------------------------------------+*/
void FixPathSlash(LPTSTR NewPath, LPTSTR Path) {
UINT PathLen;
lstrcpy(NewPath, Path);
PathLen = lstrlen(Path);
// If ending character is not a slash then put one on
if (PathLen && (Path[PathLen - 1] != '\\'))
lstrcat(NewPath, TEXT("\\"));
} // FixPathSlash
/*+-------------------------------------------------------------------------+
| ShareNameParse()
|
+-------------------------------------------------------------------------+*/
LPTSTR ShareNameParse(LPTSTR ShareName) {
ULONG i;
i = lstrlen(ShareName);
if (!i)
return ShareName;
// Scan backwards for first slash
i--;
while (i && ShareName[i] != TEXT('\\'))
i--;
// if found slash then increment past it
if (i)
i++;
return &ShareName[i];
} // ShareNameParse
static LPTSTR LocName = NULL;
/*+-------------------------------------------------------------------------+
| GetLocalName()
|
+-------------------------------------------------------------------------+*/
void GetLocalName(LPTSTR *lpLocalName) {
int size;
if (LocName != NULL) {
*lpLocalName = LocName;
} else {
LocName = AllocMemory((MAX_COMPUTERNAME_LENGTH + 1) * sizeof(TCHAR));
size = MAX_COMPUTERNAME_LENGTH + 1;
if (LocName) {
GetComputerName(LocName, &size);
*lpLocalName = LocName;
} else
*lpLocalName = NULL;
}
} // GetLocalName
/*+-------------------------------------------------------------------------+
| SetProvider()
|
+-------------------------------------------------------------------------+*/
BOOL SetProvider(LPTSTR Provider, NETRESOURCE *ResourceBuf) {
ResourceBuf->dwScope = RESOURCE_GLOBALNET;
ResourceBuf->dwType = RESOURCETYPE_DISK;
ResourceBuf->dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
// Don't take the frigging _RESERVED flag out - it isn't documented except in the include
// file and it crashes without it!
ResourceBuf->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
ResourceBuf->lpLocalName = NULL;
ResourceBuf->lpRemoteName = Provider;
ResourceBuf->lpComment = NULL;
ResourceBuf->lpProvider = Provider;
return TRUE;
} // SetProvider
/*+-------------------------------------------------------------------------+
| AllocEnumBuffer()
|
+-------------------------------------------------------------------------+*/
ENUM_REC *AllocEnumBuffer() {
ENUM_REC *Buf;
Buf = (ENUM_REC *) AllocMemory(sizeof(ENUM_REC));
if (Buf) {
// Init the record
Buf->next = NULL;
Buf->cEntries = 0;
Buf->cbBuffer = 0;
Buf->lpnr = NULL;
}
return Buf;
} // AllocEnumBuffer
/*+-------------------------------------------------------------------------+
| EnumBufferBuild()
|
| Uses WNetEnum to enumerate the resource. WNetEnum is really brain-
| dead so we need to create a temporary holding array and then build
| up a finalized complete buffer in the end. A linked list of inter-
| mediate buffer records is created first.
|
+-------------------------------------------------------------------------+*/
DWORD FAR PASCAL EnumBufferBuild(ENUM_REC **BufHead, int *NumBufs, NETRESOURCE ResourceBuf) {
DWORD status = ERROR_NO_NETWORK;
ENUM_REC *CurrBuf;
DWORD dwResultEnum;
HANDLE hEnum = NULL;
DWORD cbBuffer = 16384; // 16K default buffer size.
DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries
ENUM_REC **lppEnumRec;
LPNETRESOURCE lpnrLocal;
status = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, &ResourceBuf, &hEnum);
if (status == NO_ERROR) {
*BufHead = NULL;
lppEnumRec = BufHead;
do {
cbBuffer = 16384; // 16K default buffer size
cEntries = 0xFFFFFFFF; // enumerate all possible entries
// Allocate memory for NETRESOURCE structures.
lpnrLocal = (LPNETRESOURCE) AllocMemory(cbBuffer);
if (lpnrLocal == NULL) {
status = ERROR_NOT_ENOUGH_MEMORY;
break;
}
dwResultEnum = WNetEnumResource(hEnum, &cEntries, (LPVOID) lpnrLocal, &cbBuffer);
if (dwResultEnum == NO_ERROR) {
// Create a new Enum rec and link it to the chain
*lppEnumRec = AllocEnumBuffer();
if (*lppEnumRec == NULL) {
status = ERROR_NOT_ENOUGH_MEMORY;
break;
}
CurrBuf = *lppEnumRec;
// Init for next loop through buffer
lppEnumRec = &CurrBuf->next;
// Put enumeration buffer in our Enum rec.
CurrBuf->lpnr = lpnrLocal;
CurrBuf->cEntries = cEntries;
CurrBuf->cbBuffer = cbBuffer;
(*NumBufs)++;
} else { // Since this is not assigned in a rec we need to free it here.
FreeMemory((HGLOBAL) lpnrLocal);
if (dwResultEnum != ERROR_NO_MORE_ITEMS) {
status = dwResultEnum;
break;
}
}
} while (dwResultEnum != ERROR_NO_MORE_ITEMS);
status = WNetCloseEnum(hEnum);
}
return status;
} // EnumBufferBuild
/*+-------------------------------------------------------------------------+
| UseAddPswd()
|
| Attempts to make connections to \\szServer\admin$, asking for
| passwords if necessary.
|
| Returns TRUE if use was added,
| FALSE otherwise
|
+-------------------------------------------------------------------------+*/
BOOL UseAddPswd(HWND hwnd, LPTSTR UserName, LPTSTR lpszServer, LPTSTR lpszShare, LPTSTR Provider) {
WORD nState;
WORD fCancel;
DLGPROC lpProc;
NETRESOURCE nr;
NET_API_STATUS retcode;
LPTSTR lpPassword;
static TCHAR szTmp[MAX_UNC_PATH+1];
ServName = lpszServer;
nr.dwScope = 0;
nr.dwType = RESOURCETYPE_DISK;
nr.dwDisplayType = 0;
nr.dwUsage = 0;
nr.lpProvider = NULL;
nState = 1; // try default password
lpPassword = NULL;
BadPassword = FALSE;
lstrcpy(szUserName, UserName);
for(;;) {
// Concatenate server and share
wsprintf(szTmp, TEXT("%s\\%s"), lpszServer, lpszShare);
// Fill in data structure
nr.lpLocalName = NULL;
nr.lpRemoteName = szTmp;
nr.lpProvider = Provider;
// Try to make the connection
if (lstrlen(szUserName))
retcode = WNetAddConnection2(&nr, lpPassword, szUserName, 0);
else
retcode = WNetAddConnection2(&nr, lpPassword, NULL, 0);
switch(retcode) {
case NERR_Success:
lstrcpy(UserName, szUserName);
return TRUE;
case ERROR_INVALID_PASSWORD:
BadPassword = TRUE;
break;
case ERROR_ACCESS_DENIED:
case ERROR_NETWORK_ACCESS_DENIED:
case ERROR_SESSION_CREDENTIAL_CONFLICT:
case ERROR_NO_SUCH_USER:
case ERROR_NO_MORE_ITEMS:
case ERROR_LOGON_FAILURE:
BadPassword = FALSE;
break;
case ERROR_BAD_NETPATH:
case ERROR_BAD_NET_NAME:
default:
return FALSE;
}
// Get new password from user
lpProc = MakeProcInstance(PasswordDlgProc, hInst);
fCancel = !DialogBoxParam(hInst, TEXT("PasswordEnter"), hwnd, lpProc, 0);
// Gamble call only once
FreeProcInstance(lpProc);
// Save...
if(!fCancel) {
if(nState) {
nState = 2; // try specified password
lpPassword = szPassword;
} else {
nState = 1; // try default password
lpPassword = NULL;
}
} else {
SetLastError(ERROR_SUCCESS); // just aborting...
return FALSE;
}
}
} // UseAddPswd
/*+-------------------------------------------------------------------------+
| PasswordDlgProc()
|
| Gets a password from the user and copies it into the string pointed
| to by lParam. This string must have room for at least (PWLEN + 1)
| characters. Returns TRUE if OK is pressed, or FALSE if Cancel
|
+-------------------------------------------------------------------------+*/
LRESULT CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_INITDIALOG:
CursorNormal();
// Center the dialog over the application window
CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
SetDlgItemText(hDlg, IDC_SERVNAME, ServName);
SendDlgItemMessage(hDlg, IDC_PASSWORD, EM_LIMITTEXT, PWLEN, 0L);
SendDlgItemMessage(hDlg, IDC_USERNAME, EM_LIMITTEXT, MAX_USER_NAME_LEN, 0L);
PostMessage(hDlg, WM_COMMAND, ID_INIT, 0L);
break;
case WM_COMMAND:
switch(wParam) {
case IDOK:
CursorHourGlass();
GetDlgItemText(hDlg, IDC_PASSWORD, szPassword, PWLEN+1);
GetDlgItemText(hDlg, IDC_USERNAME, szUserName, MAX_USER_NAME_LEN+1);
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
CursorHourGlass();
EndDialog(hDlg, FALSE);
break;
case ID_INIT:
SendDlgItemMessage(hDlg, IDC_USERNAME, WM_SETTEXT, 0, (LPARAM) szUserName);
if (BadPassword)
SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
else {
SetFocus(GetDlgItem(hDlg, IDC_USERNAME));
SendDlgItemMessage(hDlg, IDC_USERNAME, EM_SETSEL, 0, (LPARAM) MAKELPARAM(0, -1) );
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
} // PasswordDlgProc
/*+-------------------------------------------------------------------------+
| NicePath()
|
+-------------------------------------------------------------------------+*/
LPTSTR NicePath(int Len, LPTSTR Path) {
static TCHAR NewPath[MAX_PATH + 80];
int eptr, fptr;
// If the path fits then just return it
if (lstrlen(Path) <= Len) {
lstrcpy(NewPath, Path);
return NewPath;
}
// The path doesn't fit, so need to reduce it down in size - to do this first try
// to get the last part of the path looking for slash that starts it.
eptr = fptr = 0;
while (Path[eptr] != TEXT('\0'))
eptr++;
// back up before ending NULL also before any ending slash
eptr--;
while ((Path[eptr] == TEXT('\\')) && eptr > 0)
eptr--;
// now try to find beginning slash
while ((Path[eptr] != TEXT('\\')) && eptr > 0)
eptr--;
// if at beginning of string then is just one name so copy all of it we can
if (eptr == 0) {
lstrcpyn(NewPath, Path, Len);
return NewPath;
}
// check if the name after the last slash can all fit - also take into account
// the "..." we are going to tack into the name
fptr = lstrlen(Path) - eptr;
fptr += 4;
if (fptr >= Len) {
lstrcpyn(NewPath, &Path[eptr], Len);
return NewPath;
}
// We need to create a path shortening to the desired length by removing the mid
// part of the path and replacing it with "..."
fptr = Len - fptr;
lstrcpyn(NewPath, Path, fptr);
lstrcat(NewPath, TEXT("..."));
lstrcat(NewPath, &Path[eptr]);
return NewPath;
} // NicePath