|
|
#define UNICODE
#define _UNICODE
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <npapi.h>
#include <winsock.h>
#include <wsnetbs.h>
#include <ras.h>
#include <raserror.h>
#include <rasdlg.h>
#include <tapi.h>
#include <commctrl.h> // added to be "Fusionized"
#include <shfusion.h> // added to be "Fusionized"
#include "process.h"
//
// Whistler bug 293751 rasphone.exe / rasautou.exe need to be "Fusionized" for
// UI conistency w/Connections Folder
//
HANDLE g_hModule = NULL; //
// All projection types. Used to
// determine if a connection was
// completed.
//
#define MAX_PROJECTIONS 5
struct RASPROJECTIONINFO { DWORD dwTag; DWORD dwSize; } projections[MAX_PROJECTIONS] = { RASP_Amb, sizeof (RASAMB), RASP_PppNbf, sizeof (RASPPPNBF), RASP_PppIpx, sizeof (RASPPPIPX), RASP_PppIp, sizeof (RASPPPIP), RASP_PppLcp, sizeof (RASPPPLCP) };
//
// Timer thread information.
//
typedef struct _TIMER_INFO { HANDLE hEvent; DWORD dwTimeout; } TIMER_INFO, *PTIMER_INFO;
//
// Private rasdlg functions.
//
DWORD RasAutodialQueryDlgW( IN HWND hwnd, IN PWCHAR pszAddress, IN PWCHAR pszEntry, IN DWORD dwTimeout, OUT PWCHAR pszEntrySelectedByUser );
BOOLEAN RasAutodialDisableDlgW( HWND hwnd );
PSYSTEM_PROCESS_INFORMATION GetSystemProcessInfo()
/*++
DESCRIPTION Return a block containing information about all processes currently running in the system.
ARGUMENTS None.
RETURN VALUE A pointer to the system process information or NULL if it could not be allocated or retrieved.
--*/
{ NTSTATUS status = STATUS_SUCCESS; PUCHAR pLargeBuffer; ULONG ulcbLargeBuffer = 64 * 1024;
//
// Get the process list.
//
for (;;) { pLargeBuffer = VirtualAlloc( NULL, ulcbLargeBuffer, MEM_COMMIT, PAGE_READWRITE); if (pLargeBuffer == NULL) { printf( "GetSystemProcessInfo: VirtualAlloc failed (status=0x%x)\n", status); return NULL; }
status = NtQuerySystemInformation( SystemProcessInformation, pLargeBuffer, ulcbLargeBuffer, NULL); if (status == STATUS_SUCCESS) break; if (status == STATUS_INFO_LENGTH_MISMATCH) { VirtualFree(pLargeBuffer, 0, MEM_RELEASE); ulcbLargeBuffer += 8192; } }
return (PSYSTEM_PROCESS_INFORMATION)pLargeBuffer; } // GetSystemProcessInfo
PSYSTEM_PROCESS_INFORMATION FindProcessByName( IN PSYSTEM_PROCESS_INFORMATION pProcessInfo, IN LPWSTR lpExeName )
/*++
DESCRIPTION Given a pointer returned by GetSystemProcessInfo(), find a process by name.
ARGUMENTS pProcessInfo: a pointer returned by GetSystemProcessInfo().
lpExeName: a pointer to a Unicode string containing the process to be found.
RETURN VALUE A pointer to the process information for the supplied process or NULL if it could not be found.
--*/
{ PUCHAR pLargeBuffer = (PUCHAR)pProcessInfo; ULONG ulTotalOffset = 0;
//
// Look in the process list for lpExeName.
//
for (;;) { if (pProcessInfo->ImageName.Buffer != NULL) { if (!_wcsicmp(pProcessInfo->ImageName.Buffer, lpExeName)) return pProcessInfo; } //
// Increment offset to next process information block.
//
if (!pProcessInfo->NextEntryOffset) break; ulTotalOffset += pProcessInfo->NextEntryOffset; pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&pLargeBuffer[ulTotalOffset]; }
return NULL; } // FindProcessByName
VOID FreeSystemProcessInfo( IN PSYSTEM_PROCESS_INFORMATION pProcessInfo )
/*++
DESCRIPTION Free a buffer returned by GetSystemProcessInfo().
ARGUMENTS pProcessInfo: the pointer returned by GetSystemProcessInfo().
RETURN VALUE None.
--*/
{ VirtualFree((PUCHAR)pProcessInfo, 0, MEM_RELEASE); } // FreeSystemProcessInfo
DWORD ActiveConnections() { DWORD dwErr, dwcbConnections = 0, dwcConnections = 0; DWORD i, j, dwTmp, dwSize; RASCONN rasconn; LPRASCONN lpRasCon = &rasconn; RASCONNSTATUS rasconnstatus;
//
// Determine how much memory we
// need to allocate.
//
lpRasCon->dwSize = sizeof (RASCONN); dwErr = RasEnumConnections(lpRasCon, &dwcbConnections, &dwcConnections); if (dwErr == ERROR_BUFFER_TOO_SMALL) { lpRasCon = LocalAlloc(LPTR, dwcbConnections); if (lpRasCon == NULL) return 0; //
// Call again to fill the buffer.
//
lpRasCon->dwSize = sizeof (RASCONN); dwErr = RasEnumConnections(lpRasCon, &dwcbConnections, &dwcConnections); } if (dwErr) goto done;
dwTmp = dwcConnections; for (i = 0; i < dwTmp; i++) { rasconnstatus.dwSize = sizeof (RASCONNSTATUS); dwErr = RasGetConnectStatus( lpRasCon[i].hrasconn, &rasconnstatus); if (dwErr || rasconnstatus.rasconnstate != RASCS_Connected) dwcConnections--; }
done: if (lpRasCon != &rasconn) LocalFree(lpRasCon); return dwErr ? 0 : dwcConnections; } // ActiveConnections
void TapiLineCallback( IN DWORD hDevice, IN DWORD dwMessage, IN ULONG_PTR dwInstance, IN ULONG_PTR dwParam1, IN ULONG_PTR dwParam2, IN ULONG_PTR dwParam3 ) { } // TapiLineCallback
DWORD GetCurrentDialingLocation() { DWORD dwErr, dwcDevices, dwLocationID; HLINEAPP hlineApp; LINETRANSLATECAPS caps; LINETRANSLATECAPS *pCaps;
//
// Initialize TAPI.
//
dwErr = lineInitialize( &hlineApp, GetModuleHandle(NULL), TapiLineCallback, NULL, &dwcDevices); if (dwErr) return 0; //
// Get the dialing location from TAPI.
//
RtlZeroMemory(&caps, sizeof (LINETRANSLATECAPS)); caps.dwTotalSize = sizeof (LINETRANSLATECAPS); dwErr = lineGetTranslateCaps(hlineApp, 0x10004, &caps); if (dwErr) return 0; pCaps = (LINETRANSLATECAPS *)LocalAlloc(LPTR, caps.dwNeededSize); if (pCaps == NULL) return 0; RtlZeroMemory(pCaps, sizeof (LINETRANSLATECAPS)); pCaps->dwTotalSize = caps.dwNeededSize; dwErr = lineGetTranslateCaps(hlineApp, 0x10004, pCaps); if (dwErr) { LocalFree(pCaps); return 0; } dwLocationID = pCaps->dwCurrentLocationID; LocalFree(pCaps); //
// Shutdown TAPI.
//
dwErr = lineShutdown(hlineApp);
return dwLocationID; } // GetCurrentDialingLocation
DWORD TimerThread( LPVOID lpArg ) { NTSTATUS status; PTIMER_INFO pTimerInfo = (PTIMER_INFO)lpArg; HANDLE hEvent = pTimerInfo->hEvent; DWORD dwTimeout = pTimerInfo->dwTimeout;
LocalFree(pTimerInfo); //
// Wait for the timeout period. If hEvent
// gets signaled before the timeout period
// expires, then the user has addressed the
// dialog and we return. Otherwise, we simply
// exit.
//
if (WaitForSingleObject(hEvent, dwTimeout * 1000) == WAIT_TIMEOUT) exit(1);
return 0; } // TimerThread
DWORD DisplayRasDialog( IN LPTSTR pszPhonebook, IN LPTSTR pszEntry, IN LPTSTR pszAddress, IN BOOLEAN fRedialMode, IN BOOLEAN fQuiet ) { NTSTATUS status; DWORD dwErr = 0, dwSize, dwCount = 0; DWORD dwcConnections, dwfDisableConnectionQuery; DWORD dwPreDialingLocation, dwPostDialingLocation; DWORD dwConnectionQueryTimeout; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; PSYSTEM_PROCESS_INFORMATION pSystemInfo; BOOLEAN fCancelled; LPRASAUTODIALENTRY pAutodialEntries = NULL; DWORD dwcbAutodialEntries = 0, dwcAutodialEntries = 0; WCHAR pszNewEntry[RAS_MaxEntryName + 1];
wcscpy(pszNewEntry, L"\0");
//
// Check to see if the user has disabled
// the Autodial query dialog when the
// phonebook entry to dial is known.
//
if (fRedialMode || fQuiet) dwfDisableConnectionQuery = TRUE; else { dwSize = sizeof (DWORD); (void)RasGetAutodialParam( RASADP_DisableConnectionQuery, &dwfDisableConnectionQuery, &dwSize); } //
// Ask the user if he wants to dial if either the
// phonebook entry is not known or the user has
// not disabled the "always ask me before dialing"
// parameter.
//
// If RasDialDlg() returns FALSE, the user didn't
// want to dial.
//
if (pszEntry == NULL || !dwfDisableConnectionQuery) { dwSize = sizeof (DWORD); (void)RasGetAutodialParam( RASADP_ConnectionQueryTimeout, &dwConnectionQueryTimeout, &dwSize); //
// Save the current dialing location to
// see if the user changed it inside the
// dialog.
//
dwPreDialingLocation = GetCurrentDialingLocation(); dwErr = RasAutodialQueryDlgW( NULL, pszAddress, pszEntry, dwConnectionQueryTimeout, pszNewEntry);
// Whistler: 255816
//
// Only disable the address if an error occurs.
// If the user simply types 'no' then CANCEL is
// returned from rasdlg, but we'll return NO_ERROR to the
// rasauto service so that the address remains enabled.
//
if (dwErr == ERROR_CANCELLED) { return NO_ERROR; } else if (dwErr != NO_ERROR) { return ERROR_CANCELLED; } dwPostDialingLocation = GetCurrentDialingLocation(); //
// If the user changed the dialing location
// within the dialog, then get the new entry.
//
if (dwPreDialingLocation != dwPostDialingLocation) { pszEntry = NULL; dwErr = RasGetAutodialAddress( pszAddress, NULL, NULL, &dwcbAutodialEntries, &dwcAutodialEntries); if (dwErr == ERROR_BUFFER_TOO_SMALL && dwcAutodialEntries) pAutodialEntries = LocalAlloc(LPTR, dwcbAutodialEntries); if (dwcAutodialEntries && pAutodialEntries != NULL) { pAutodialEntries[0].dwSize = sizeof (RASAUTODIALENTRY); dwErr = RasGetAutodialAddress( pszAddress, NULL, pAutodialEntries, &dwcbAutodialEntries, &dwcAutodialEntries); if (!dwErr) { DWORD i;
for (i = 0; i < dwcAutodialEntries; i++) { if (pAutodialEntries[i].dwDialingLocation == dwPostDialingLocation) { pszEntry = pAutodialEntries[i].szEntry; break; } } } } }
// Whistler: new autodial UI
//
// The connection that the user wants to dial will be in
// pszNewEntry.
//
else { if (*pszNewEntry) { pszEntry = pszNewEntry; } }
}
if (pszEntry) { RASDIALDLG info;
ZeroMemory( &info, sizeof(info) ); info.dwSize = sizeof(info);
//
// Prevent the DialerDialog to come up only if the
// user has checked the don't query before dialing
// checkbox. Otherwise we bringup the dialog.
//
if(dwfDisableConnectionQuery) { info.dwFlags |= RASDDFLAG_NoPrompt; }
if (fRedialMode) { /* Set this flag to tell RasDialDlg to popup the "reconnect
** pending" countdown dialog before redialing. */ info.dwFlags |= RASDDFLAG_LinkFailure; }
/* Popup the "Dial-Up Networking" dialing dialogs.
*/ fCancelled = !RasDialDlg( pszPhonebook, pszEntry, NULL, &info ); } else if (!fQuiet) { RASPBDLG info;
ZeroMemory( &info, sizeof(info) ); info.dwSize = sizeof(info); info.dwFlags = RASPBDFLAG_ForceCloseOnDial;
/* Popup the main "Dial-Up Networking" dialog.
*/ fCancelled = !RasPhonebookDlg( pszPhonebook, NULL, &info ); }
if (!fRedialMode && !fQuiet && fCancelled) { /* User did not make a connection. Ask him if he wants to nix
** auto-dial for this location. */ // if (RasAutodialDisableDlgW( NULL ))
// RasSetAutodialEnable( GetCurrentDialingLocation(), FALSE );
}
if (pAutodialEntries != NULL) LocalFree(pAutodialEntries);
return 0; } // DisplayRasDialog
DWORD GetExpandedDllPath(LPTSTR pszDllPath, LPTSTR *ppszExpandedDllPath) { DWORD dwErr = 0; DWORD dwSize = 0;
//
// find the size of the expanded string
//
if (0 == (dwSize = ExpandEnvironmentStrings(pszDllPath, NULL, 0))) { dwErr = GetLastError(); goto done; }
*ppszExpandedDllPath = LocalAlloc( LPTR, dwSize * sizeof (TCHAR)); if (NULL == *ppszExpandedDllPath) { dwErr = GetLastError(); goto done; }
//
// Get the expanded string
//
if (0 == ExpandEnvironmentStrings( pszDllPath, *ppszExpandedDllPath, dwSize)) { dwErr = GetLastError(); }
done: return dwErr; }
LPWSTR ConvertToUnicodeString( LPSTR psz )
// Modified to use code from nouiutil
{ WCHAR* pszNew = NULL;
if (psz) { DWORD cb;
cb = MultiByteToWideChar( CP_ACP, 0, psz, -1, NULL, 0 ); ASSERT(cb);
pszNew = LocalAlloc( LPTR, (cb + 1) * sizeof(TCHAR) ); if (!pszNew) { printf("rasautou: LocalAlloc failed\n"); return NULL; }
cb = MultiByteToWideChar( CP_ACP, 0, psz, -1, pszNew, cb ); if (cb == 0) { LocalFree( pszNew ); printf("rasautou: multibyte string conversion failed\n"); return NULL; } }
return pszNew; } // ConvertToUnicodeString
LPSTR ConvertToAnsiString( PWCHAR psz )
// Modified to use code from nouiutil
{ CHAR* pszNew = NULL;
if (psz) { DWORD cb;
cb = WideCharToMultiByte( CP_ACP, 0, psz, -1, NULL, 0, NULL, NULL ); ASSERT(cb);
pszNew = (CHAR* )LocalAlloc( LPTR, cb + 1 ); if (!pszNew) { printf("rasautou: LocalAlloc failed"); return NULL; }
cb = WideCharToMultiByte( CP_ACP, 0, psz, -1, pszNew, cb, NULL, NULL ); if (cb == 0) { LocalFree( pszNew ); printf("rasautou: wide-character string conversion failed"); return NULL; } }
return pszNew; } // ConvertToUnicodeString
DWORD DisplayCustomDialog( IN LPTSTR pszDll, IN LPTSTR pszFunc, IN LPTSTR pszPhonebook, IN LPTSTR pszEntry, IN LPTSTR pszAddress ) { DWORD dwErr, dwRetCode; HINSTANCE hLibrary; CHAR szFuncNew[64], szFuncOld[64], *pszOldFunc = NULL; ORASADFUNC pfnOldStyleFunc; RASADFUNC pfnFunc; RASADPARAMS params; LPTSTR pszExpandedPath = NULL; CHAR * pszEntryA = NULL;
dwErr = GetExpandedDllPath(pszDll, &pszExpandedPath);
if(ERROR_SUCCESS != dwErr) { return dwErr; }
//
// Load the library.
//
hLibrary = LoadLibrary(pszExpandedPath); if (hLibrary == NULL) { dwErr = GetLastError(); printf( "rasdlui: %s: AutoDial DLL cannot be loaded (dwErr=%d)\n", pszDll, dwErr);
LocalFree(pszExpandedPath); return dwErr; } //
// Get the procedure address. First,
// we check for a new-style entry point,
// and then check for an old-style entry
// point if the new-style one doesn't exist.
//
#ifdef UNICODE
sprintf(szFuncNew, "%SW", pszFunc); pszOldFunc = ConvertToAnsiString(pszFunc); pszEntryA = ConvertToAnsiString(pszEntry);
if (!pszOldFunc || !pszEntryA) { printf("rasautou: Allocation failed. Exiting\n"); exit(1); } #else
sprintf(szFuncNew, "%sA", pszFunc); strcpy(szFuncOld, pszFunc); pszOldFunc = szFuncOld; pszEntryA = pszEntry; #endif
pfnFunc = (RASADFUNC)GetProcAddress(hLibrary, szFuncNew); if (pfnFunc != NULL) { //
// Initialize the param block.
//
params.hwndOwner = NULL; params.dwFlags = 0; params.xDlg = params.yDlg = 0; //params.dwCallbackId = 0;
//params.pCallback = NULL;
//
// Call the procedure.
//
(*pfnFunc)(pszPhonebook, pszEntry, ¶ms, &dwRetCode); } else { pfnOldStyleFunc = (ORASADFUNC)GetProcAddress(hLibrary, pszOldFunc); if (pfnOldStyleFunc != NULL) { (*pfnOldStyleFunc)(NULL, pszEntryA, 0, &dwRetCode); } else { #ifdef UNICODE
printf( "rasautou: %S: Function cannot be loaded from AutoDial DLL %S\n", pszDll, pszFunc); #else
printf( "rasautou: %s: Function cannot be loaded from AutoDial DLL %s\n", pszDll, pszFunc); #endif
exit(1); } } //
// Clean up.
//
FreeLibrary(hLibrary);
#ifdef UNICODE
if (pszOldFunc) { LocalFree(pszOldFunc); } if (pszEntryA) { LocalFree(pszOldFunc); } #endif
LocalFree(pszExpandedPath); return dwRetCode; } // DisplayCustomDialog
VOID FreeConvertedString( IN LPWSTR pwsz ) { if (pwsz != NULL) LocalFree(pwsz); } // FreeConvertedString
BOOLEAN RegGetValueA( IN HKEY hkey, IN LPSTR pszKey, OUT PVOID *ppvData, OUT LPDWORD pdwcbData ) { DWORD dwError, dwType, dwSize; PVOID pvData;
//
// Get the length of the string.
//
dwError = RegQueryValueExA( hkey, pszKey, NULL, &dwType, NULL, &dwSize); if (dwError != ERROR_SUCCESS) return FALSE; pvData = LocalAlloc(LPTR, dwSize); if (pvData == NULL) { DbgPrint("RegGetValueA: LocalAlloc failed\n"); return FALSE; } //
// Read the value for real this time.
//
dwError = RegQueryValueExA( hkey, pszKey, NULL, NULL, (LPBYTE)pvData, &dwSize); if (dwError != ERROR_SUCCESS) { LocalFree(pvData); return FALSE; }
*ppvData = pvData; if (pdwcbData != NULL) *pdwcbData = dwSize; return TRUE; } // RegGetValueA
VOID NetworkConnected()
/*++
DESCRIPTION Determine whether there exists some network connection.
Note: This code was stolen from sockit.c courtesy of ArnoldM.
ARGUMENTS None
RETURN VALUE TRUE if one exists, FALSE otherwise.
--*/
{ typedef struct _LANA_MAP { BOOLEAN fEnum; UCHAR bLana; } LANA_MAP, *PLANA_MAP; BOOLEAN fNetworkPresent = FALSE; HKEY hKey; PLANA_MAP pLanaMap = NULL, pLana; DWORD dwError, dwcbLanaMap; PCHAR pMultiSzLanasA = NULL, paszTemp; DWORD dwcBindings, dwcMaxLanas, i, dwcbLanas; LONG iLana; DWORD dwZero = 0; PCHAR *paszLanas = NULL; SOCKET s; SOCKADDR_NB nbaddress, nbsendto; NTSTATUS status; UNICODE_STRING deviceName; OBJECT_ATTRIBUTES attributes; IO_STATUS_BLOCK iosb; HANDLE handle; PWCHAR pwsz;
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\Netbios\\Linkage", 0, KEY_READ, &hKey); if (dwError != ERROR_SUCCESS) { printf( "NetworkConnected: RegKeyOpenEx failed (dwError=%d)\n", GetLastError()); return; } //
// Read in the LanaMap.
//
if (!RegGetValueA(hKey, "LanaMap", &pLanaMap, &dwcbLanaMap)) { printf("NetworkConnected: RegGetValueA(LanaMap) failed\n"); goto done; } dwcBindings = dwcbLanaMap / sizeof (LANA_MAP); //
// Read in the bindings.
//
if (!RegGetValueA(hKey, "bind", &pMultiSzLanasA, &dwcbLanas)) { printf("NetworkConnected: RegGetValueA(bind) failed\n"); goto done; } //
// Allocate a buffer for the binding array.
//
paszLanas = LocalAlloc(LPTR, (dwcBindings+1) * sizeof (PCHAR)); if (paszLanas == NULL) { printf("NetworkConnected: LocalAlloc failed\n"); goto done; } //
// Parse the bindings into an array of strings.
//
for (dwcMaxLanas = 0, paszTemp = pMultiSzLanasA; *paszTemp; paszTemp++) { paszLanas[dwcMaxLanas++] = paszTemp; while(*++paszTemp); } //
// Finally enumerate the bindings and
// attempt to create a socket on each.
//
nbaddress.snb_family = AF_NETBIOS; nbaddress.snb_type = 0; memcpy(nbaddress.snb_name, "yahooyahoo ", 16); nbsendto.snb_family = AF_NETBIOS; nbsendto.snb_type = 0; memcpy(nbsendto.snb_name, "billybob ", 16);
for (iLana = 0, pLana = pLanaMap; dwcBindings--; iLana++, pLana++) { int iLanaMap = (int)pLana->bLana;
if (pLana->fEnum && (DWORD)iLana < dwcMaxLanas) { int iError;
if (!_stricmp(paszLanas[iLana], "\\Device\\NwlnkNb") || strstr(paszLanas[iLana], "_NdisWan") != NULL) { printf("NetworkConnected: ignoring %s\n", paszLanas[iLana]); continue; }
#ifdef notdef
s = socket(AF_NETBIOS, SOCK_DGRAM, -iLanaMap); if (s == INVALID_SOCKET) { printf( "NetworkConnected: socket(%s, %d) failed (error=%d)\n", paszLanas[iLana], iLana, WSAGetLastError()); continue; } //printf("s=0x%x, iLana=%d, %s\n", s, iLana, paszLanas[iLana]);
iError = ioctlsocket(s, FIONBIO, &dwZero); if (iError == SOCKET_ERROR) { printf( "NetworkConnected: ioctlsocket(%s) failed (error=%d)\n", paszLanas[iLana], iLana, WSAGetLastError()); goto cleanup; } iError = bind( s, (struct sockaddr *)&nbaddress, sizeof(nbaddress)); if (iError == SOCKET_ERROR) { printf( "NetworkConnected: bind(%s, %d) failed (error=%d)\n", paszLanas[iLana], iLana, WSAGetLastError()); goto cleanup; } iError = sendto( s, (PCHAR)&nbsendto, sizeof (nbsendto), 0, (struct sockaddr *)&nbsendto, sizeof (nbsendto)); if (iError == SOCKET_ERROR) { printf( "NetworkConnected: sendto(%s, %d) failed (error=%d)\n", paszLanas[iLana], iLana, WSAGetLastError()); } cleanup: closesocket(s); if (iError != SOCKET_ERROR) { printf("NetworkConnected: network (%s, %d) is up\n", paszLanas[iLana], iLana); fNetworkPresent = TRUE; break; } #else
pwsz = ConvertToUnicodeString(paszLanas[iLana]); RtlInitUnicodeString(&deviceName, pwsz); InitializeObjectAttributes( &attributes, &deviceName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = NtOpenFile(&handle, READ_CONTROL, &attributes, &iosb, 0, 0); NtClose(handle);
LocalFree(pwsz);
if (NT_SUCCESS(status)) { printf( "NetworkConnected: network (%s, %d) is up\n", paszLanas[iLana], iLana); fNetworkPresent = TRUE; break; } else { printf( "NetworkConnected: NtOpenFile on %s failed (status=0x%x)\n", paszLanas[iLana], status); } #endif
} } //
// Free resources.
//
done: if (paszLanas != NULL) LocalFree(paszLanas); if (pMultiSzLanasA != NULL) LocalFree(pMultiSzLanasA); if (pLanaMap != NULL) LocalFree(pLanaMap); RegCloseKey(hKey); } // NetworkConnected
VOID DumpAutoDialAddresses() { DWORD dwErr, i, dwcb, dwcAddresses; LPTSTR *lppAddresses = NULL;
dwErr = RasEnumAutodialAddresses(NULL, &dwcb, &dwcAddresses); if (dwErr && dwErr != ERROR_BUFFER_TOO_SMALL) { printf("RasEnumAutodialAddresses failed (dwErr=%d)\n", dwErr); return; } if (dwcAddresses) { lppAddresses = (LPTSTR *)LocalAlloc(LPTR, dwcb); if (lppAddresses == NULL) { printf("LocalAlloc failed\n"); return; } dwErr = RasEnumAutodialAddresses(lppAddresses, &dwcb, &dwcAddresses); if (dwErr) { printf("RasEnumAutodialAddresses failed (dwErr=%d)\n", dwErr); LocalFree(lppAddresses); return; } } printf("There are %d Autodial addresses:\n", dwcAddresses); for (i = 0; i < dwcAddresses; i++) #ifdef UNICODE
printf("%S\n", lppAddresses[i]); #else
printf("%s\n", lppAddresses[i]); #endif
if (lppAddresses != NULL) LocalFree(lppAddresses); } // DumpAutoDialAddresses
VOID DumpStatus() { DWORD dwErr; WSADATA wsaData;
//
// Initialize winsock.
//
dwErr = WSAStartup(MAKEWORD(2,0), &wsaData); if (dwErr) { DbgPrint("AcsInitialize: WSAStartup failed (dwErr=%d)\n", dwErr); return; } //
// Display network connectivity.
//
printf("Checking netcard bindings...\n"); NetworkConnected(); //
// Display AutoDial address table.
//
printf("\nEnumerating AutoDial addresses...\n"); DumpAutoDialAddresses(); } // DumpStatus
// Returns true if a redial-on-link-failure process is
// active.
//
BOOL OtherRasautouExists( IN PSYSTEM_PROCESS_INFORMATION pProcessInfo) { PUCHAR pLargeBuffer = (PUCHAR)pProcessInfo; ULONG ulTotalOffset = 0; DWORD dwProcId, dwSessId = 0; BOOL fValidSessId = FALSE;
dwProcId = GetCurrentProcessId(); fValidSessId = ProcessIdToSessionId(dwProcId, &dwSessId);
//printf(
// "ProcId=%d, SessId=%d, ValSess=%d\n", dwProcId, dwSessId, fValidSessId);
//
// Look in the process list for lpExeName.
//
for (;;) { if (pProcessInfo->ImageName.Buffer != NULL) { // If
// 1. The process is in our session
// 2. It is not us
// 3. It is rasautou
//
// Then another rasautou is already active -- we should
// return success so that no ui is raised.
//
//printf(
// "id=%-2d, sess=%-4d, %S\n",
// PtrToUlong(pProcessInfo->UniqueProcessId),
// pProcessInfo->SessionId,
// pProcessInfo->ImageName.Buffer);
if ( ((dwSessId == pProcessInfo->SessionId) || (!fValidSessId)) && (PtrToUlong(pProcessInfo->UniqueProcessId) != dwProcId) && (_wcsicmp(pProcessInfo->ImageName.Buffer, L"rasautou.exe") == 0) ) { //
// We could actually check that
// 4. That rasautou function is started with the -r flag
//
// However, it doesn't hurt to return if this is any rasautou
// prompt.
//
return TRUE; } } //
// Increment offset to next process information block.
//
if (!pProcessInfo->NextEntryOffset) { break; } ulTotalOffset += pProcessInfo->NextEntryOffset; pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&pLargeBuffer[ulTotalOffset]; }
return FALSE; } // FindProcessByName
//
// Determines whether any redial on link failure prompts are
// currently active.
//
BOOL OtherRasautouActive() { BOOL bRet = FALSE; PSYSTEM_PROCESS_INFORMATION pSysInfo = NULL; do { // Discover the processes on the system
//
pSysInfo = GetSystemProcessInfo(); if (pSysInfo == NULL) { break; }
// Find out if any rasautou processes are active
//
bRet = OtherRasautouExists(pSysInfo); } while (FALSE);
// Cleanup
//
{ if (pSysInfo) { FreeSystemProcessInfo(pSysInfo); } }
//printf("OtherRasautouActive() returned %s", (bRet) ? "true" : "false");
return bRet; }
VOID _cdecl wmain( INT argc, WCHAR **argv ) { DWORD dwErr = 0; BOOLEAN fStatusFlag = FALSE, fRedialFlag = FALSE, fQuiet = FALSE; PWCHAR pszPhonebookArg, pszEntryArg, pszDllArg, pszFuncArg, pszAddressArg; LPTSTR pszPhonebook, pszEntry, pszDll, pszFunc, pszAddress;
//
// Whistler bug 293751 rasphone.exe / rasautou.exe need to be "Fusionized"
// for UI conistency w/Connections Folder
//
if (g_hModule = GetModuleHandle( NULL )) { SHFusionInitializeFromModule( g_hModule ); } if (argc < 2) { usage: printf( "Usage: rasautou [-f phonebook] [-d dll -p proc] [-a address] [-e entry] [-s]\n"); exit(1); } //
// Initialize the command line argument pointers.
//
pszPhonebookArg = NULL; pszEntryArg = NULL; pszDllArg = NULL; pszFuncArg = NULL; pszAddressArg = NULL;
//
// Crack command line parameters.
//
while (--argc && argv++) { if (**argv != L'-') break; switch ((*argv)[1]) { case L'a': argc--; if (!argc) goto usage; pszAddressArg = *(++argv); break; case L'd': argc--; if (!argc) goto usage; pszDllArg = *(++argv); break; case L'e': argc--; if (!argc) goto usage; pszEntryArg = *(++argv); break; case L'f': argc--; if (!argc) goto usage; pszPhonebookArg = *(++argv); break; case L'p': argc--; if (!argc) goto usage; pszFuncArg = *(++argv); break; case L'q': fQuiet = TRUE; break; case L'r': fRedialFlag = TRUE; break; case L's': fStatusFlag = TRUE; break; default: goto usage; } } //
// If either the DLL name or the function
// name is missing, then display usage.
//
if ((pszDllArg == NULL) != (pszFuncArg == NULL) && !fStatusFlag) goto usage; //
// We can't dial an entry unless we
// know which one!
//
if (pszDllArg != NULL && pszFuncArg != NULL && pszEntryArg == NULL && !fStatusFlag) { goto usage; } if (fStatusFlag) DumpStatus(); else { //
// Convert to Unicode, if necessary.
//
#ifdef UNICODE
pszPhonebook = pszPhonebookArg; pszEntry = pszEntryArg; pszDll = pszDllArg; pszFunc = pszFuncArg; pszAddress = pszAddressArg; #else
pszPhonebook = ConvertToAnsiString(pszPhonebookArg); pszEntry = ConvertToAnsiString(pszEntryArg); pszDll = ConvertToAnsiString(pszDllArg); pszFunc = ConvertToAnsiString(pszFuncArg); pszAddress = ConvertToAnsiString(pszAddressArg); #endif
// XP 394237
//
// Supress the autodial prompt if a redial-on-link-failure
// prompt is already active
//
if ((fRedialFlag) || (fQuiet) || (!OtherRasautouActive())) { //
// Call the appropriate DLL entrypoint.
//
if ((pszDll == NULL && pszFunc == NULL) || fRedialFlag) { dwErr = DisplayRasDialog( pszPhonebook, pszEntry, pszAddress, fRedialFlag, fQuiet); } else { dwErr = DisplayCustomDialog( pszDll, pszFunc, pszPhonebook, pszEntry, pszAddress); } } #ifndef UNICODE
FreeConvertedString(pszPhonebook); FreeConvertedString(pszEntry); FreeConvertedString(pszDll); FreeConvertedString(pszFunc); FreeConvertedString(pszAddress); #endif
} //
// Whistler bug 293751 rasphone.exe / rasautou.exe need to be "Fusionized"
// for UI conistency w/Connections Folder
//
if (g_hModule) { SHFusionUninitialize(); } //
// Return status.
//
exit(dwErr); }
|