/*++ Copyright (c) 1997 Microsoft Corporation Module Name: w9xtool.c Abstract: Implements a stub tool that is designed to run with Win9x-side upgrade code. Author: () Revision History: --*/ #include "pch.h" typedef struct _IPData { DWORD dwSize; DWORD fdwTCPIP; DWORD dwIPAddr; DWORD dwDNSAddr; DWORD dwDNSAddrAlt; DWORD dwWINSAddr; DWORD dwWINSAddrAlt; } IPDATA, *PIPDATA; typedef struct _AddrEntry { DWORD dwVersion; DWORD dwCountryCode; UINT uOffArea; UINT uOffPhone; DWORD dwCountryID; UINT uOffSMMCfg; UINT uOffSMM; UINT uOffDI; } ADDRENTRY, *PADDRENTRY; typedef struct _SubConnEntry { DWORD dwSize; DWORD dwFlags; char szDeviceType[RAS_MaxDeviceType+1]; char szDeviceName[RAS_MaxDeviceName+1]; char szLocal[RAS_MaxPhoneNumber+1]; } SUBCONNENTRY, *PSUBCONNENTRY; typedef struct _DEVICEINFO { DWORD dwVersion; UINT uSize; char szDeviceName[RAS_MaxDeviceName+1]; char szDeviceType[RAS_MaxDeviceType+1]; } DEVICEINFO, *PDEVICEINFO; typedef struct _SMMCFG { DWORD dwSize; DWORD fdwOptions; DWORD fdwProtocols; } SMMCFG, *PSMMCFG; typedef struct { DWORD Size; DWORD Unknown1; DWORD ModemUiOptions; // num seconds in high byte. DWORD Unknown2; DWORD Unknown3; DWORD Unknown4; DWORD ConnectionSpeed; DWORD UnknownFlowControlData; //Somehow related to flow control. DWORD Unknown5; DWORD Unknown6; DWORD Unknown7; DWORD Unknown8; DWORD Unknown9; DWORD Unknown10; DWORD Unknown11; DWORD Unknown12; DWORD Unknown13; DWORD Unknown14; DWORD Unknown15; DWORD CancelSeconds; //Num seconds to wait before cancel if not connected. (0xFF equals off.) DWORD IdleDisconnectSeconds; // 0 = Not Set. DWORD Unknown16; DWORD SpeakerVolume; // 0|1 DWORD ConfigOptions; DWORD Unknown17; DWORD Unknown18; DWORD Unknown19; } MODEMDEVINFO, *PMODEMDEVINFO; #define RAS_UI_FLAG_TERMBEFOREDIAL 0x1 #define RAS_UI_FLAG_TERMAFTERDIAL 0x2 #define RAS_UI_FLAG_OPERATORASSISTED 0x4 #define RAS_UI_FLAG_MODEMSTATUS 0x8 #define RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL 0x00000010 #define RAS_CFG_FLAG_SOFTWARE_FLOW_CONTROL 0x00000020 #define RAS_CFG_FLAG_STANDARD_EMULATION 0x00000040 #define RAS_CFG_FLAG_COMPRESS_DATA 0x00000001 #define RAS_CFG_FLAG_USE_ERROR_CONTROL 0x00000002 #define RAS_CFG_FLAG_ERROR_CONTROL_REQUIRED 0x00000004 #define RAS_CFG_FLAG_USE_CELLULAR_PROTOCOL 0x00000008 #define RAS_CFG_FLAG_NO_WAIT_FOR_DIALTONE 0x00000200 PCTSTR g_User = NULL; PCTSTR g_Setting = NULL; PCTSTR g_Entry = NULL; BOOL g_ShowBinary = FALSE; #define S_REMOTE_ACCESS_KEY TEXT("RemoteAccess") #define S_PROFILE_KEY TEXT("RemoteAccess\\Profile") #define S_ADDRESSES_KEY TEXT("RemoteAccess\\Addresses") #define S_DIALUI TEXT("DialUI") #define S_ENABLE_REDIAL TEXT("EnableRedial") #define S_REDIAL_WAIT TEXT("RedialWait") #define S_REDIAL_TRY TEXT("RedialTry") #define S_ENABLE_IMPLICIT TEXT("EnableImplicit") #define S_TERMINAL TEXT("Terminal") #define S_MODE TEXT("Mode") #define S_MULTILINK TEXT("MultiLink") #define DIALUI_DONT_PROMPT_FOR_INFO 0x01 #define DIALUI_DONT_SHOW_CONFIRM_DIALOG 0x02 #define DIALUI_DONT_SHOW_ICON 0x04 #define SMMCFG_TCPIP_PROTOCOL 0x04 #define SMMCFG_NETBEUI_PROTOCOL 0x01 #define SMMCFG_IPXSPX_PROTOCOL 0x02 #define PAESMMCFG(pAE) ((PSMMCFG)(((PBYTE)pAE)+(pAE->uOffSMMCfg))) #define PAESMM(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffSMM))) #define PAEDI(pAE) ((PDEVICEINFO)(((PBYTE)pAE)+(pAE->uOffDI ))) #define PAEAREA(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffArea))) #define PAEPHONE(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffPhone))) #define DECRYPTENTRY(x, y, z) EnDecryptEntry(x, (LPBYTE)y, z) static BYTE NEAR PASCAL GenerateEncryptKey (LPSTR szKey) { BYTE bKey; LPBYTE lpKey; for (bKey = 0, lpKey = (LPBYTE)szKey; *lpKey != 0; lpKey++) { bKey += *lpKey; }; return bKey; } DWORD NEAR PASCAL EnDecryptEntry (LPSTR szEntry, LPBYTE lpEnt, DWORD cb); VOID pDumpPerUserSettings ( IN HKEY UserKey ) { HKEY settingsKey; PDWORD data; printf("\n*** Ras Per User Setting Information ***\n"); settingsKey = OpenRegKey(UserKey,S_REMOTE_ACCESS_KEY); if (settingsKey) { // // Get UI settings. // data = (PDWORD) GetRegValueBinary(settingsKey,S_DIALUI); printf("\n\t** Dialup UI Information **\n"); if (data) { printf("\t\t%sprompt for information before dialing.\n", DIALUI_DONT_PROMPT_FOR_INFO & *data ? "Don't " :"" ); printf("\t\t%sshow confirmation dialog after connected.\n", DIALUI_DONT_SHOW_CONFIRM_DIALOG & *data ? "Don't ":"" ); printf("\t\t%sshow an icon on the taskbar after connected.\n", DIALUI_DONT_SHOW_ICON & *data ? "Don't ":"" ); MemFree(g_hHeap,0,data); } else { printf("\t\tNo user UI Settings found..\n"); } // // Get Redial information. // printf("\n\t** Redialing Information **\n"); data = (PDWORD) GetRegValueBinary(settingsKey,S_ENABLE_REDIAL); if (data) { printf("\t\tRedialing %s.\n",*data ? "Enabled." : "Disabled."); MemFree(g_hHeap,0,data); } else { printf("\t\tNo Redial information found.\n"); } data = (PDWORD) GetRegValueBinary(settingsKey,S_REDIAL_TRY); if (data) { printf("\t\tNumber of redial tries: %u.\n", *data); MemFree(g_hHeap,0,data); } data = (PDWORD) GetRegValueBinary(settingsKey,S_REDIAL_WAIT); if (data) { printf("\t\tRedial time in seconds: %u\n", HIWORD(*data) * 60 + LOWORD(*data)); MemFree(g_hHeap,0,data); } // // Get implicit connection information. // data = (PDWORD) GetRegValueBinary(settingsKey,S_ENABLE_IMPLICIT); if (data) { printf("\n\t%sprompt with dial-up networking to establish connection.\n", *data ? "" : "Don't " ); MemFree(g_hHeap,0,data); } CloseRegKey(settingsKey); } printf("\n***\n"); } PTSTR pIpAddressAsString( DWORD dwAddress ) { BYTE bAddress[4]; static TCHAR address[30]; *((LPDWORD)bAddress) = dwAddress; sprintf(address,"%d.%d.%d.%d", bAddress[0], bAddress[1], bAddress[2],bAddress[3]); return address; } VOID pDumpBinaryData( IN PBYTE Data, IN UINT Size ) { UINT i,j; TCHAR hexArray[40]; TCHAR strArray[20]; TCHAR buf[20]; printf("\n\t\tBinary Dump...\n"); for (j = 0;j fTcpIp = %u\n",IpData -> fdwTCPIP); printf("\t\t IP Address = %s\n",pIpAddressAsString(IpData -> dwIPAddr)); printf("\t\t DNS Address = %s\n",pIpAddressAsString(IpData -> dwDNSAddr)); printf("\t\t Alternate DNS Address = %s\n",pIpAddressAsString(IpData -> dwDNSAddrAlt)); printf("\t\t WINS Address = %s\n",pIpAddressAsString(IpData -> dwWINSAddr)); printf("\t\t Alternate WINS Address = %s\n",pIpAddressAsString(IpData -> dwWINSAddrAlt)); } VOID pDumpConnectionSettings ( IN HANDLE Key, IN PCTSTR Name ) { REGVALUE_ENUM e; PBYTE curData; printf("\n\t** %s Setting.. **\n",Name); if (EnumFirstRegValue(&e,Key)) { do { // // Get the data for this entry. // curData = GetRegValueData(Key,e.ValueName); if (curData) { if (!g_Setting || StringIMatch(g_Setting,e.ValueName)) { switch (e.Type) { case REG_SZ: case REG_MULTI_SZ: case REG_EXPAND_SZ: printf("\t\t %s = %s\n",e.ValueName,(PCTSTR) curData); break; case REG_DWORD: printf("\t\t %s = %u\n",e.ValueName,*((PDWORD) curData)); break; case REG_BINARY: if (StringIMatch(S_IPINFO,e.ValueName)) { pDumpIpInformation((PIPDATA) curData); } else if (StringIMatch(S_TERMINAL,e.ValueName)) { PWINDOWPLACEMENT wp = (PWINDOWPLACEMENT) curData; PCTSTR showStr = NULL; switch(wp -> showCmd) { case SW_HIDE: showStr = "SW_HIDE"; break; case SW_MINIMIZE: showStr = "SW_MINIMIZE"; break; case SW_RESTORE: showStr = "SW_RESTORE"; break; case SW_SHOW: showStr = "SW_SHOW"; break; case SW_SHOWMAXIMIZED: showStr = "SW_SHOWMAXIMIZED"; break; case SW_SHOWMINIMIZED: showStr = "SW_SHOWMINIMIZED"; break; case SW_SHOWMINNOACTIVE: showStr = "SW_SHOWMINNOACTIVE"; break; case SW_SHOWNA: showStr = "SW_SHOWNA"; break; case SW_SHOWNOACTIVATE: showStr = "SW_SHOWNOACTIVATE"; break; case SW_SHOWNORMAL: showStr = "SW_SHOWNORMAL"; break; default: showStr = "Unknown SHOW FLAG!"; break; } printf("\t\tTerminal Window Show Flag: %s\n", showStr); } else if (StringIMatch(S_MODE,e.ValueName)) { if (*curData) { printf("\t\tStep through script. (Testing Mode..)\n"); } else { printf("\t\tScript should be run in normal mode.\n"); } } else if (StringIMatch(S_MULTILINK,e.ValueName)) { printf("\t\tMultilink is %s.\n",*curData ? "ENABLED" : "DISABLED"); } else { printf("\t\t %s = \n",e.ValueName); } if (g_ShowBinary) { pDumpBinaryData(curData,e.DataSize); } break; default: printf("\t\t %s = \n",e.ValueName); break; } } MemFree(g_hHeap,0,curData); } } while (EnumNextRegValue(&e)); } } VOID pDumpDevInfo ( IN PDEVICEINFO Info ) { UINT size; UINT i; PMODEMDEVINFO caps; printf ("** Device Info: \n" "\t\tVersion: %u \n" "\t\tSize: %u\n" "\t\tDevice Name: %s\n" "\t\tDevice Type: %s\n", Info->dwVersion, Info->uSize, Info->szDeviceName, Info->szDeviceType ); size = Info->uSize - ((PBYTE) (Info->szDeviceType + RAS_MaxDeviceType + 1) - (PBYTE) Info); caps = (PMODEMDEVINFO) (Info->szDeviceType + RAS_MaxDeviceType + 3); #if 0 pDumpBinaryData ((PBYTE) caps, sizeof (REGDEVCAPS)); printf ("As Dwords..\n"); for (i = 0; i < 27; i++) { printf ("Dword %u = %u (%x)\n",i, caps->foo[i], caps->foo[i]); } #endif printf ( "\tCaps Size: %u\n" "\tStart Term Before Redial? %s\n" "\tStart Term After Redial? %s\n" "\tOperator Assited Dial? %s\n" "\tShow Modem Status? %s\n" "\tUI Options: %u (%x)\n" "\tConnection Speed: %u\n" "\tCancel if not connected within %u seconds.\n" "\tDisconnect if Idle for %u seconds.\n" "\tSpeaker %s.\n" "\tHardware Flow Control? %s\n" "\tSoftware Flow Control? %s\n" "\tStandard Emulation? %s\n" "\tCompress Data? %s\n" "\tUse Error Control? %s\n" "\tError Control Required? %s\n" "\tUse Cellular Protocol? %s\n" "\tWait for Dialtone? %s\n" "\tConfig Options: %u (%x)\n", caps->Size, caps->ModemUiOptions & RAS_UI_FLAG_TERMBEFOREDIAL ? "Yes" : "No", caps->ModemUiOptions & RAS_UI_FLAG_TERMAFTERDIAL ? "Yes" : "No", caps->ModemUiOptions & RAS_UI_FLAG_OPERATORASSISTED ? "Yes" : "No", caps->ModemUiOptions & RAS_UI_FLAG_MODEMSTATUS ? "Yes" : "No", caps->ModemUiOptions, caps->ModemUiOptions, caps->ConnectionSpeed, caps->CancelSeconds, caps->IdleDisconnectSeconds, caps->SpeakerVolume ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_SOFTWARE_FLOW_CONTROL ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_STANDARD_EMULATION ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_COMPRESS_DATA ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_USE_ERROR_CONTROL ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_ERROR_CONTROL_REQUIRED ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_USE_CELLULAR_PROTOCOL ? "Yes" : "No", caps->ConfigOptions & RAS_CFG_FLAG_NO_WAIT_FOR_DIALTONE ? "No" : "Yes", caps->ConfigOptions, caps->ConfigOptions ); } VOID pDumpAddressInfo ( IN HKEY AddressKey, IN PCTSTR SubKeyName ) { PBYTE data = NULL; UINT count = 0; UINT type = 0; PADDRENTRY entry; PSMMCFG smmCfg; PDEVICEINFO devInfo; UINT sequencer = 0; HKEY subEntriesKey; PTSTR subEntriesKeyStr; REGVALUE_ENUM eSubEntries; PSUBCONNENTRY subEntry; if (RegQueryValueEx(AddressKey, SubKeyName, NULL, &type, NULL, &count) == ERROR_SUCCESS) { data = MemAlloc(g_hHeap,0,count); if (data) { if (RegQueryValueEx(AddressKey, SubKeyName, NULL, &type, (LPBYTE)data,&count) == ERROR_SUCCESS) { entry = (PADDRENTRY) data; DECRYPTENTRY((PTSTR)SubKeyName, entry, count); smmCfg = PAESMMCFG(entry); devInfo = PAEDI(entry); pDumpDevInfo (devInfo); if (!g_Setting || StringMatch(g_Setting,"AddressData")) { printf("\t\t Phone Number = %s\n",PAEPHONE(entry)); printf("\t\t Area Code = %s\n",PAEAREA(entry)); printf("\t\t SMM = %s\n",PAESMM(entry)); printf("\t\t Country Code = %u\n",entry -> dwCountryCode); printf("\t\t Country Id = %u\n",entry -> dwCountryID); printf("\t\t DeviceName = %s\n",devInfo -> szDeviceName); printf("\t\t DeviceType = %s\n",devInfo -> szDeviceType); printf("\t\t Options = %u\n",smmCfg -> fdwOptions); printf("\t\t TCPIP is %s.\n", smmCfg -> fdwProtocols & SMMCFG_TCPIP_PROTOCOL ? "ENABLED" : "DISABLED"); printf("\t\t NETBEUI is %s.\n", smmCfg -> fdwProtocols & SMMCFG_NETBEUI_PROTOCOL ? "ENABLED" : "DISABLED"); printf("\t\t IPX/SPX is %s.\n", smmCfg -> fdwProtocols & SMMCFG_IPXSPX_PROTOCOL ? "ENABLED" : "DISABLED"); if (g_ShowBinary) { pDumpBinaryData((PBYTE) entry,count); } } } MemFree(g_hHeap,0,data); subEntriesKeyStr = JoinPaths ("SubEntries", SubKeyName); subEntriesKey = OpenRegKey (AddressKey, subEntriesKeyStr); FreePathString (subEntriesKeyStr); sequencer = 0; if (subEntriesKey) { if (EnumFirstRegValue (&eSubEntries, subEntriesKey)) { do { data = GetRegValueBinary (subEntriesKey, eSubEntries.ValueName); if (data) { subEntry = (PSUBCONNENTRY) data; DECRYPTENTRY ((PTSTR) SubKeyName, subEntry, eSubEntries.DataSize); printf ("\tSub Entry Device Type: %s\n", subEntry->szDeviceType); printf ("\tSub Entry Device Name: %s\n", subEntry->szDeviceName); printf ("\tSub Entry Phone Number: %s\n", subEntry->szDeviceName); printf ("\tSub Entry Flags: %u (%x)\n", subEntry->dwFlags); printf ("\tSub Entry Size: %u\n", subEntry->dwSize); pDumpBinaryData ((PBYTE) subEntry, subEntry->dwSize); MemFree (g_hHeap, 0, data); } sequencer++; } while (EnumNextRegValue (&eSubEntries)); } CloseRegKey (subEntriesKey); } } } } VOID pDumpPerConnectionSettings ( IN HKEY UserKey ) { REGKEY_ENUM e; HKEY profileKey; HKEY entryKey = NULL; HKEY addressKey = NULL; printf("\n*** Ras Per Connection Setting Information ***\n"); profileKey = OpenRegKey (UserKey,S_PROFILE_KEY); addressKey = OpenRegKey (UserKey,S_ADDRESSES_KEY); if (profileKey && addressKey) { if (EnumFirstRegKey(&e,addressKey)) { do { if (!g_Entry || StringIMatch(g_Entry,e.SubKeyName)) { pDumpAddressInfo(addressKey,e.SubKeyName); entryKey = OpenRegKey(profileKey,e.SubKeyName); if (entryKey ) { pDumpConnectionSettings (entryKey, e.SubKeyName); CloseRegKey(entryKey); } } } while (EnumNextRegKey(&e)); } } CloseRegKey(addressKey); CloseRegKey(profileKey); printf("\n***\n"); } BOOL Init ( VOID ) { HINSTANCE hInstance; hInstance = GetModuleHandle (NULL); return InitToolMode (hInstance); } VOID Terminate ( VOID ) { HINSTANCE hInstance; hInstance = GetModuleHandle (NULL); TerminateToolMode (hInstance); } VOID pShowHelp ( VOID ) { printf("\nUsage: RasDump [-h?b] [-u:] [-e:] [-s:]\n" "\n\t\t -h - Display this message." "\n\t\t -? - Display this message." "\n\t\t -u - Dump information for user ." "\n\t\t -b - Dump raw binary data." "\n\t\t -e - Dump Entry infor for DialUp Connection .\n"); exit(0); } VOID pProcessCommandLine ( UINT argc, PTSTR * argv ) { UINT i; PTSTR p; for (i = 1;i < argc; i++) { p = argv[i]; if (*p != TEXT('-') && *p != TEXT('/')) { pShowHelp(); } p++; switch(tolower(*p)) { case TEXT('u'): if (*++p != ':') { pShowHelp(); } g_User = ++p; break; case TEXT('s'): if (*++p != ':') { pShowHelp(); } g_Setting = ++p; break; case TEXT('h'): case TEXT('?'): pShowHelp(); break; case TEXT('e'): if (*++p != ':') { pShowHelp(); } g_Entry = ++p; break; case TEXT('b') : g_ShowBinary = TRUE; break; default: pShowHelp(); break; } } } INT __cdecl main ( INT argc, CHAR *argv[] ) { USERENUM e; TCHAR buf[MEMDB_MAX]; if (!Init()) { printf ("Unable to initialize!\n"); return 255; } // // needed by enumuser.. // GetWindowsDirectory(buf,MAX_PATH); g_WinDir = buf; Win95RegInit(g_WinDir,NULL); pProcessCommandLine(argc,argv); if (EnumFirstUser (&e, ENUMUSER_ENABLE_NAME_FIX)) { do { if (!g_User || StringIMatch(g_User,e.UserName)) { printf("Dumping ras settings for user %s..\n",*e.UserName ? e.UserName : ""); __try { pDumpPerUserSettings(e.UserRegKey); pDumpPerConnectionSettings(e.UserRegKey); } except (1) { printf("Caught an exception.."); } } } while (EnumNextUser(&e)); } Terminate(); return 0; }