|
|
/*
+-------------------------------------------------------------------------+ | 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 = (DLGPROC) 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
|