Posted: . At: 8:54 AM. This was 1 year ago. Post ID: 17305
Page permalink. WordPress uses cookies, or tiny pieces of information stored on your computer, to verify who you are. There are cookies for logged in users and for commenters.
These cookies expire two weeks after they are set.


Some information I found about the Internet Explorer browser of old.


I have found out more information about the old Internet Explorer browser used on Windows XP. Useful registry keys are used by the browser to store and retrieve information.

“HKCU\\Software\\Microsoft\\Office\\10.0\\Common\\LanguageResources\\UILanguage”. This is used by the browser to get the language used by the operating system.

This registry key contains the product ID of Internet Explorer.

    // Hey, they're pointing to our PID!  That's cool.
    StrCpyN(pdwsm->szPIDRegKey, 
           "HKLM\\Software\\Microsoft\\Internet Explorer\\Registration\\DigitalProductID", DW_MAX_PATH);

This code sample is a section of the Internet Explorer source code. This shows the startup process of the browser.

iexplore\mainloop.cpp
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
    //
    // We don't want the "No disk in drive X:" requesters, so we set
    // the critical error mask such that calls will just silently fail
    //
 
    SetErrorMode(SEM_FAILCRITICALERRORS);
 
    if(StopWatchMode() & SPMODE_BROWSER)  // Used to get the start of browser total download time
    {
        StopWatch_Start(SWID_BROWSER_FRAME, TEXT("Browser Frame Start"), SPMODE_BROWSER | SPMODE_DEBUGOUT);
    }
 
    if ( *pszCmdLine == TEXT('\"') ) {
        /*
         * Scan, and skip over, subsequent characters until
         * another double-quote or a null is encountered.
         */
        while ( *++pszCmdLine && (*pszCmdLine
             != TEXT('\"')) );
        /*
         * If we stopped on a double-quote (usual case), skip
         * over it.
         */
        if ( *pszCmdLine == TEXT('\"') )
            pszCmdLine++;
    }
    else {
        while (*pszCmdLine > TEXT(' '))
            pszCmdLine++;
    }
 
    /*
     * Skip past any white space preceeding the second token.
     */
    while (*pszCmdLine && (*pszCmdLine <= TEXT(' '))) {
        pszCmdLine++;
    }
 
    si.dwFlags = 0;
    si.cb = sizeof(si);
 
    GetStartupInfoA(&si);
 
    i = WinMainT(GetModuleHandle(NULL), NULL, (LPTSTR)pszCmdLine,
                   si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
 
#ifndef UNIX  
    ExitThread(i);  // We only come here when we are not the shell...
#else
// there seem to be some desirable side effect calling ExitThread on Windows
    ExitProcess(i); 
#endif
    return i;
}
 
//
// Create a unique event name
//
HANDLE AppendEvent(COPYDATASTRUCT *pcds)
{
    static DWORD dwNextID = 0;
    TCHAR szEvent[MAX_IEEVENTNAME];
 
    wsprintf(szEvent, "IE-%08X-%08X", GetCurrentThreadId(), dwNextID++);
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, szEvent);
    if (hEvent)
    {
        //
        // Put the (UNICODE) event name at the end of the cds data
        //
        LPWSTR pwszBufferEvent = (LPWSTR)(((BYTE *)pcds->lpData) + pcds->cbData);
#ifdef UNICODE
        lstrcpy(pwszBufferEvent, szEvent);
#else
        MultiByteToWideChar(CP_ACP, 0, szEvent, -1, pwszBufferEvent, ARRAYSIZE(szEvent));
#endif
        pcds->cbData += (lstrlenW(pwszBufferEvent) + 1) * sizeof(WCHAR);
    }
 
    return hEvent;
}
 
BOOL IsCommandSwitch(LPTSTR lpszCmdLine, LPTSTR pszSwitch, BOOL fRemoveSwitch)
{
    LPTSTR lpsz;
 
    if ((lpsz=StrStrI(lpszCmdLine, pszSwitch)) && (lpsz == lpszCmdLine))
    {
        int cch = lstrlen(pszSwitch);
 
        if (*(lpsz+cch) == 0 || *(lpsz+cch) == TEXT(' '))
        {
            while (*(lpsz+cch) == TEXT(' '))
                cch++;
 
            if (fRemoveSwitch)
            {
                // Remove the switch by copying everything up.
                *lpsz=0;
                lstrcat(lpsz, lpsz+cch);
            }
            return TRUE;
        }
    } 
    return FALSE;
}
 
BOOL CheckForNeedingAppCompatWindow(void)
{
    // Which I could simply get the Process of who spawned me.  For now
    // try hack to get the foreground window and go from there...
    TCHAR szClassName[80];
    HWND hwnd = GetForegroundWindow();
 
    if (hwnd && GetClassName(hwnd, szClassName, ARRAYSIZE(szClassName)) > 0)
    {
        if (lstrcmpi(szClassName, TEXT("MauiFrame")) == 0)
            return TRUE;
    }
    return FALSE;
}
 
//
// AppCompat - Sequel NetPIM execs a browser and then waits forever
// looking for a visible top level window owned by this process.
//
HWND CreateAppCompatWindow(HINSTANCE hinst)
{
    HWND hwnd;
    static const TCHAR c_szClass[] = TEXT("IEDummyFrame");  // IE3 used "IEFrame"
 
    WNDCLASS wc = { 0, DefWindowProc, 0, 0, hinst, NULL, NULL, NULL, NULL, c_szClass };
    RegisterClass(&wc);
 
    // Netmanage ECCO Pro asks to get the menu...
    HMENU hmenu = CreateMenu();
    hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, c_szClass, TEXT(""), 0,
                          0x00007FF0, 0x00007FF0, 0, 0,
                          NULL, hmenu, hinst, NULL);
    // Don't open SHOWDEFAULT or this turkey could end up maximized
    ShowWindow(hwnd, SW_SHOWNA);
 
    return hwnd;
}
 
#define USERAGENT_POST_PLATFORM_PATH_TO_KEY    TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\User Agent\\Post Platform")
void SetCompatModeUserAgentString(void)
{
    HKEY hkey;
    const char szcompat[]=TEXT("compat");
 
    if (ERROR_SUCCESS == RegCreateKey(HKEY_CURRENT_USER, USERAGENT_POST_PLATFORM_PATH_TO_KEY, &hkey))
    {
        RegSetValueEx( hkey,
                       szcompat,
                       0,
                       REG_BINARY,
                       (LPBYTE)NULL, 0);
        RegCloseKey(hkey);
    }
 
}
 
// Tell the user they are running in compat mode and not all the features will be available.
#define IECOMPAT_REG_VAL    TEXT("CompatWarningFor")
 
void WarnCompatMode(HINSTANCE hinst)
{
    TCHAR szFqFilename[MAX_PATH];
    TCHAR szRegVal[MAX_PATH];
    TCHAR szTitle[255];
    TCHAR szMsg[1024];
    LPTSTR szFile;
 
    GetModuleFileName(NULL, szFqFilename, ARRAYSIZE(szFqFilename));
    szFile = PathFindFileName(szFqFilename);
 
 
    // Build up string "compatmodewarningfor <exe name>" as value for reg key
    lstrcpy(szRegVal, IECOMPAT_REG_VAL);
    lstrcat(szRegVal, szFile);
 
    LoadString(hinst, IDS_COMPATMODEWARNINGTITLE, szTitle, ARRAYSIZE(szTitle));
    LoadString(hinst, IDS_COMPATMODEWARNING, szMsg, ARRAYSIZE(szMsg));
 
    SHMessageBoxCheck(NULL, szMsg, szTitle, MB_OK, FALSE, szRegVal);
}
 
#ifdef WINNT
 
// this is the same code that is in explorer.exe (initcab.c)
#define RSA_PATH_TO_KEY    TEXT("Software\\Microsoft\\Cryptography\\Defaults\\Provider\\Microsoft Base Cryptographic Provider v1.0")
#define CSD_REG_PATH       TEXT("System\\CurrentControlSet\\Control\\Windows")
#define CSD_REG_VALUE      TEXT("CSDVersion")
 
 
// the signatures we are looking for in the regsitry so that we can patch up 
 
#ifdef _M_IX86
static  BYTE  SP3Sig[] = {0xbd, 0x9f, 0x13, 0xc5, 0x92, 0x12, 0x2b, 0x72,
                          0x4a, 0xba, 0xb6, 0x2a, 0xf9, 0xfc, 0x54, 0x46,
                          0x6f, 0xa1, 0xb4, 0xbb, 0x43, 0xa8, 0xfe, 0xf8,
                          0xa8, 0x23, 0x7d, 0xd1, 0x85, 0x84, 0x22, 0x6e,
                          0xb4, 0x58, 0x00, 0x3e, 0x0b, 0x19, 0x83, 0x88,
                          0x6a, 0x8d, 0x64, 0x02, 0xdf, 0x5f, 0x65, 0x7e,
                          0x3b, 0x4d, 0xd4, 0x10, 0x44, 0xb9, 0x46, 0x34,
                          0xf3, 0x40, 0xf4, 0xbc, 0x9f, 0x4b, 0x82, 0x1e,
                          0xcc, 0xa7, 0xd0, 0x2d, 0x22, 0xd7, 0xb1, 0xf0,
                          0x2e, 0xcd, 0x0e, 0x21, 0x52, 0xbc, 0x3e, 0x81,
                          0xb1, 0x1a, 0x86, 0x52, 0x4d, 0x3f, 0xfb, 0xa2,
                          0x9d, 0xae, 0xc6, 0x3d, 0xaa, 0x13, 0x4d, 0x18,
                          0x7c, 0xd2, 0x28, 0xce, 0x72, 0xb1, 0x26, 0x3f,
                          0xba, 0xf8, 0xa6, 0x4b, 0x01, 0xb9, 0xa4, 0x5c,
                          0x43, 0x68, 0xd3, 0x46, 0x81, 0x00, 0x7f, 0x6a,
                          0xd7, 0xd1, 0x69, 0x51, 0x47, 0x25, 0x14, 0x40,
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#else // other than _M_IX86
static  BYTE  SP3Sig[] = {0x8a, 0x06, 0x01, 0x6d, 0xc2, 0xb5, 0xa2, 0x66,
                          0x12, 0x1b, 0x9c, 0xe4, 0x58, 0xb1, 0xf8, 0x7d,
                          0xad, 0x17, 0xc1, 0xf9, 0x3f, 0x87, 0xe3, 0x9c,
                          0xdd, 0xeb, 0xcc, 0xa8, 0x6b, 0x62, 0xd0, 0x72,
                          0xe7, 0xf2, 0xec, 0xd6, 0xd6, 0x36, 0xab, 0x2d,
                          0x28, 0xea, 0x74, 0x07, 0x0e, 0x6c, 0x6d, 0xe1,
                          0xf8, 0x17, 0x97, 0x13, 0x8d, 0xb1, 0x8b, 0x0b,
                          0x33, 0x97, 0xc5, 0x46, 0x66, 0x96, 0xb4, 0xf7,
                          0x03, 0xc5, 0x03, 0x98, 0xf7, 0x91, 0xae, 0x9d,
                          0x00, 0x1a, 0xc6, 0x86, 0x30, 0x5c, 0xc8, 0xc7,
                          0x05, 0x47, 0xed, 0x2d, 0xc2, 0x0b, 0x61, 0x4b,
                          0xce, 0xe5, 0xb7, 0xd7, 0x27, 0x0c, 0x9e, 0x2f,
                          0xc5, 0x25, 0xe3, 0x81, 0x13, 0x9d, 0xa2, 0x67,
                          0xb2, 0x26, 0xfc, 0x99, 0x9d, 0xce, 0x0e, 0xaf,
                          0x30, 0xf3, 0x30, 0xec, 0xa3, 0x0a, 0xfe, 0x16,
                          0xb6, 0xda, 0x16, 0x90, 0x9a, 0x9a, 0x74, 0x7a,
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#endif      // _M_IX86
 
void CheckForSP3RSAOverwrite( void )
{
    // check for them having installed NTSP3 over the top of IE4, it nukes
    // the RSABASE reg stuff, so we have to re-do it. (our default platform is NT + SP3, but this
    // problem doesn't occur on NT5, so ignore it.
 
    OSVERSIONINFO osVer;
 
    ZeroMemory(&osVer, sizeof(osVer));
    osVer.dwOSVersionInfoSize = sizeof(osVer);
 
    if( GetVersionEx(&osVer) && (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) 
        && (osVer.dwMajorVersion == 4))
    {
        // now check to see we are on SP3 ...
        DWORD dwValue = 0;
        DWORD dwSize = sizeof( dwValue );
 
        if ( ERROR_SUCCESS == SHGetValue( HKEY_LOCAL_MACHINE, CSD_REG_PATH, CSD_REG_VALUE, NULL,
             &dwValue, &dwSize) && LOWORD( dwValue ) == 0x300 )
        {
            BYTE rgbSig[136];
            dwSize = sizeof(rgbSig);
 
            if (ERROR_SUCCESS == SHGetValue ( HKEY_LOCAL_MACHINE, RSA_PATH_TO_KEY, TEXT("Signature"), NULL,
                rgbSig, &dwSize))
            {
                if ((dwSize == sizeof(SP3Sig)) && 
                    (0 == memcmp(SP3Sig, rgbSig, sizeof(SP3Sig))))
                {
                    // need to do a DLLRegisterServer on RSABase
                    HINSTANCE hInst = LoadLibrary(TEXT("rsabase.dll"));
                    if ( hInst )
                    {
                        FARPROC pfnDllReg = GetProcAddress( hInst, "DllRegisterServer");
                        if ( pfnDllReg )
                        {
                            __try
                            {
                                pfnDllReg();
                            }
                            __except( EXCEPTION_EXECUTE_HANDLER)
                            {
                            }
                            __endexcept
                        }
 
                        FreeLibrary( hInst );
                    }
                }
            }
        }           
    }
}
#else
#define CheckForSP3RSAOverwrite() 
#endif
 
 
#define TEN_SECONDS (10 * 1000)
 
LONG WINAPI DwExceptionFilter(LPEXCEPTION_POINTERS pep)
{
    EXCEPTION_RECORD         *per;
    HANDLE                    hFileMap = NULL;
    DWSharedMem              *pdwsm = NULL;
    SECURITY_ATTRIBUTES       sa;
    LONG                      lReturn = 0;
 
    // we keep local copies of these in case another thread is trashing memory
    // it much more likely to trash the heap than our stack
    HANDLE                    hEventDone = NULL;          // event DW signals when done
    HANDLE                    hEventAlive = NULL;         // heartbeat event DW signals per EVENT_TIMEOUT
    HANDLE                    hMutex = NULL;              // to protect the signaling of EventDone  
 
    CHAR                      szCommandLine[MAX_PATH * 2];
 
    DWORD                     dwSize, dwType, dw;
    TCHAR                     tchURL[INTERNET_MAX_URL_LENGTH];
 
    BOOL                      fDwRunning;  
 
    STARTUPINFOA              si;
    PROCESS_INFORMATION       pi;
 
    // init
    if (pep)
    {
        per = pep->ExceptionRecord;
        if (EXCEPTION_BREAKPOINT == per->ExceptionCode)
            goto Cleanup;
    }
 
    // create shared memory
    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
 
    hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, 
                      sizeof(DWSharedMem), NULL);
    if (hFileMap == NULL)
    {
        lReturn = 1;
        goto Cleanup;
    }
 
    pdwsm = (DWSharedMem *) MapViewOfFile(hFileMap, 
                                          FILE_MAP_READ | FILE_MAP_WRITE,
                                          0, 0, 0);
    if (pdwsm == NULL)
    {
        lReturn = 1;
        goto Cleanup;
    }
 
    memset(pdwsm, 0, sizeof(DWSharedMem));
 
    hEventAlive = CreateEvent(&sa, FALSE, FALSE, NULL);
    hEventDone = CreateEvent(&sa, FALSE, FALSE, NULL);
    hMutex = CreateMutex(&sa, FALSE, NULL);
 
    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), 
                    GetCurrentProcess(), &pdwsm->hProc, PROCESS_ALL_ACCESS,
                    TRUE, 0))
    {
        lReturn = 1;
        goto Cleanup;
    }
 
    if (hEventAlive == NULL || hEventDone == NULL || hMutex == NULL
        || pdwsm->hProc == NULL)
    {
        lReturn = 1;
        goto Cleanup;
    }
 
    // setup interface structure
    pdwsm->pid = GetCurrentProcessId();
    pdwsm->tid = GetCurrentThreadId();
    pdwsm->hEventAlive = hEventAlive;
    pdwsm->hEventDone = hEventDone;
    pdwsm->hMutex = hMutex;
    pdwsm->dwSize = sizeof(DWSharedMem);
    pdwsm->pep = pep;
    if (pep)
        pdwsm->eip = (DWORD_PTR) pep->ExceptionRecord->ExceptionAddress;
    pdwsm->bfmsoctdsOffer = MSODWRESTARTQUIT;
    pdwsm->lcidUI = MLGetUILanguage();
 
    StrCpyNW(pdwsm->wzFormalAppName, L"Microsoft Internet Explorer", DW_APPNAME_LENGTH);
 
    StrCpyN(pdwsm->szRegSubPath, "Microsoft\\Office\\10.0\\Common", DW_MAX_REGSUBPATH);
 
    // Our language key?
    StrCpyN(pdwsm->szLCIDKeyValue, 
           "HKCU\\Software\\Microsoft\\Office\\10.0\\Common\\LanguageResources\\UILanguage", DW_MAX_PATH);
 
    // Hey, they're pointing to our PID!  That's cool.
    StrCpyN(pdwsm->szPIDRegKey, 
           "HKLM\\Software\\Microsoft\\Internet Explorer\\Registration\\DigitalProductID", DW_MAX_PATH);
 
    // Okay, I'll send it there.
    //
    dwSize = INTERNET_MAX_URL_LENGTH;
 
    if (ERROR_SUCCESS == SHGetValueA(HKEY_LOCAL_MACHINE,
                                     "Software\\Microsoft\\Internet Explorer\\Main",
                                     "IEWatsonURL",
                                     &dwType, tchURL, &dwSize))
    {
        StrCpyN(pdwsm->szServer, tchURL, DW_MAX_SERVERNAME);
    }
    else
    {
        StrCpyN(pdwsm->szServer, "watson.microsoft.com", DW_MAX_SERVERNAME);
    }
 
    // Do not set details string.
    //StrCpyNW(pdwsm->wzErrorMessage, L"Internet Explorer has encountered an internal error.", DW_MAX_ERROR_CWC);
 
    // Core modules
    StrCpyNW(pdwsm->wzDotDataDlls, L"browseui.dll\0shdocvw.dll\0mshtml.dll\0urlmon.dll\0wininet.dll\0", DW_MAX_PATH);
 
    // This will usually be "IEXPLORE.EXE"
    GetModuleFileNameWrapW(NULL, pdwsm->wzModuleFileName, DW_MAX_PATH);
 
    // ok, now we don't want to accidently change this
 
    memset(&si, 0, sizeof(STARTUPINFOA));
    si.cb = sizeof(STARTUPINFOA);
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
 
    wnsprintfA(szCommandLine, sizeof(szCommandLine),
              "dw15 -x -s %u", 
              (DWORD_PTR) hFileMap); 
 
    if (CreateProcessA(NULL, szCommandLine, NULL, NULL, TRUE, 
                  CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL,
                  NULL, &si, &pi))
    {
        fDwRunning = TRUE;
        while (fDwRunning)
        {
            if (WaitForSingleObject(hEventAlive, DW_TIMEOUT_VALUE) 
                == WAIT_OBJECT_0)
            {
                if (WaitForSingleObject(hEventDone, 1) == WAIT_OBJECT_0)
                {
                    fDwRunning = FALSE;
                }
                continue;
            }
 
             // we timed-out waiting for DW to respond, try to quit
            dw = WaitForSingleObject(hMutex, DW_TIMEOUT_VALUE);
            if (dw == WAIT_TIMEOUT)
                fDwRunning = FALSE; // either DW's hung or crashed, we must carry on  
            else if (dw == WAIT_ABANDONED)
            {
                fDwRunning = FALSE;
                ReleaseMutex(hMutex);
            }
            else
            {
                // DW has not woken up?
                if (WaitForSingleObject(hEventAlive, 1) != WAIT_OBJECT_0)
                    // tell DW we're through waiting for it's sorry self
                {
                    SetEvent(hEventDone);
                    fDwRunning = FALSE;
                }
                else
                {
                    // are we done
                    if (WaitForSingleObject(hEventDone, 1) 
                        == WAIT_OBJECT_0)
                        fDwRunning = FALSE;
                }
                ReleaseMutex(hMutex);
            }
        }
 
    } // end if CreateProcess succeeded
 
 
Cleanup:
    if (hEventAlive)
        CloseHandle(hEventAlive);
    if (hEventDone)
        CloseHandle(hEventDone);
    if (hMutex)
        CloseHandle(hMutex);
    if (pdwsm)
        UnmapViewOfFile(pdwsm);
    if (hFileMap)
        CloseHandle(hFileMap);
 
    return lReturn;
}
 
//---------------------------------------------------------------------------
int WinMainT(HINSTANCE hinst, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
{
#ifdef DEBUG
    CcshellGetDebugFlags();
#endif
    int  iRet = TRUE;
    HWND hwndDesktop ;
    BOOL fNowait = FALSE;
    BOOL fInproc = FALSE;
    BOOL fEval   = FALSE;
#ifdef UNIX
    BOOL fRemote = FALSE;
#endif

And the code below is to do with the UNIX compatibility when it runs on Sun Solaris UNIX.

unixstuff.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>
#include <mainwin.h>
 
#define IEREMOTE_CMDLINE        1
#define IEREMOTECLASS           TEXT("IEFrame")
 
BOOL ConnectRemoteIE(LPTSTR pszCmdLine, HINSTANCE hInstance);
BOOL IsCommandSwitch(LPTSTR lpszCmdLine, LPTSTR pszSwitch);
BOOL RemoteIENewWindow(LPTSTR pszCmdLine);
 
#if defined(UNIX)
 
#include <sys/time.h>
#include <sys/resource.h>
 
#define INCREASE_FILEHANDLE_LIMIT  \
    struct rlimit rl; \
    if ( 0 == getrlimit(RLIMIT_NOFILE, &rl)) { \
       rl.rlim_cur = rl.rlim_max; \
       setrlimit(RLIMIT_NOFILE, &rl); \
    } \

#endif

Finally, this is the iexplore\unixstuff.cpp file that contains more code to do with the UNIX compatibility for Internet Explorer.

unixstuff.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "iexplore.h"
#include "unixstuff.h"
 
//
// BOOL ConnectRemoteIE(LPTSTR pszCommandLine)
//
// This function will be called when -remote parameter is specified during the 
// invokation of IE. That's the same format as Netscape uses, see 
// http://home.netscape.com/newsref/std/x-remote.html. 
// For now, the only special action supported is openURL(URL), because we need 
// it for the NetShow. We just put it as the URL was specified as iexplorer 
// param. To be done - connection to the existent browser.
// Returns TRUE if succeed to connect to the existent browser.
//
#define c_szSpace TEXT(' ')
 
static BOOL IsOpenURL(LPCTSTR pszBeginCommand, LPCTSTR pszEndCommand, LPTSTR pszURL)
{
    const TCHAR c_szOpenURL[] = TEXT("openURL");
    const TCHAR c_szLBracket  = TEXT('(');
    const TCHAR c_szRBracket  = TEXT(')');
    const TCHAR c_szSQuote    = TEXT('\'');
    const TCHAR c_szDQuote  = TEXT('\"');
    LPCTSTR pszBeginURL, pszEndURL;
    BOOL bRet = TRUE;
 
    // Skip the leading/trailing spaces.
    while (*pszBeginCommand == c_szSpace) pszBeginCommand++;
    while ((*pszEndCommand == c_szSpace) && (pszBeginCommand <= pszEndCommand))
        pszEndCommand--;
 
    // Now, parse the value and replace in the cmd line, 
    // if there is openURL there. More formats later...
    if (StrCmpNI(pszBeginCommand, c_szOpenURL, lstrlen(c_szOpenURL)) ||
        (*pszEndCommand != c_szRBracket)) {
        pszBeginURL = pszBeginCommand;
        bRet = FALSE;
	pszEndURL = pszEndCommand;
    }
    else{
        pszBeginURL = pszBeginCommand+lstrlen(c_szOpenURL);
	while (*pszBeginURL == c_szSpace) pszBeginURL++;    
	if ((*pszBeginURL != c_szLBracket) || 
	    (pszBeginURL == pszEndCommand-1)) {
	    pszURL[0] = '\0';
	    return FALSE;
	}
	pszBeginURL++;
	pszEndURL = pszEndCommand-1;
    }
 
    // Skip the leading/trailing spaces.
    while (*pszBeginURL == c_szSpace) pszBeginURL++;    
    while (*pszEndURL == c_szSpace) pszEndURL--;
 
    // Take off quotes.
    if (((*pszBeginURL == c_szSQuote) && (*pszEndURL == c_szSQuote)) || 
	((*pszBeginURL == c_szDQuote) && (*pszEndURL == c_szDQuote))) {
        while (*pszBeginURL == c_szSpace) pszBeginURL++;    
	while (*pszEndURL == c_szSpace) pszEndURL--;
	if (pszBeginURL >= pszEndURL) {
	    pszURL[0] = '\0';
	    return FALSE;
	}
    }
 
    StrCpyN(pszURL, pszBeginURL, (pszEndURL-pszBeginURL)/sizeof(TCHAR) +2); 
    if (bRet) 
        bRet = pszURL[0];
 
    return bRet;
}
 
 
static BOOL ConnectExistentIE(LPCTSTR pszURL, HINSTANCE hInstance)
{
    HWND hwnd; 
 
    if (hwnd = FindWindow(IEREMOTECLASS, NULL))
    {
        COPYDATASTRUCT cds;
        cds.dwData = IEREMOTE_CMDLINE;
        cds.cbData = pszURL ? (lstrlen(pszURL)+1)*sizeof(TCHAR) : 0;
        cds.lpData = pszURL;
        SetForegroundWindow(hwnd);
        SendMessage(hwnd, WM_COPYDATA, (WPARAM)WMC_DISPATCH, (LPARAM)&cds);
	ExitProcess(0);
    }
    return FALSE;
}
 
BOOL ConnectRemoteIE(LPTSTR pszCmdLine, HINSTANCE hInstance)
{
    const TCHAR c_szDblQuote  = TEXT('"');
    const TCHAR c_szQuote     = TEXT('\'');
 
    LPTSTR pszBeginRemote, pszEndRemote;
    LPTSTR pszBeginCommand, pszEndCommand;
    TCHAR  szURL[INTERNET_MAX_URL_LENGTH];
    TCHAR  szRestCmdLine[INTERNET_MAX_URL_LENGTH * 2];
 
    // If we start with a quote, finish with a quote.
    // If we start with something else, finish 1 symbol before space
    // or end of string.
    pszBeginRemote = pszBeginCommand = pszCmdLine;
 
    if (*pszBeginCommand == c_szQuote || *pszBeginCommand == c_szDblQuote) {
        pszEndRemote = pszEndCommand = StrChr(pszBeginCommand+1, (WORD)(*pszBeginCommand));
        pszBeginCommand++;       
    }
    else {
        pszEndCommand = StrChr(pszBeginCommand, (WORD)c_szSpace);
        if (pszEndCommand == NULL)
            pszEndCommand = pszBeginCommand+lstrlen(pszBeginCommand);
       pszEndRemote = pszEndCommand-1;
    }
 
    if ((pszEndCommand == NULL) || (lstrlen(pszBeginCommand) <= 1))
        return FALSE;
    pszEndCommand--;
 
    //
    // Now, check the remote command and execute.
    // For now, we just replace the URL in the cmd line, 
    // if there is openURL there. More formats later...
    IsOpenURL(pszBeginCommand, pszEndCommand, szURL);
    if (ConnectExistentIE(szURL, hInstance))
        return TRUE;
    StrCpyN(szRestCmdLine, pszEndRemote+1, ARRAYSIZE(szRestCmdLine));
    *pszBeginRemote = '\0';   
    StrCat(pszCmdLine, szURL);
    StrCat(pszCmdLine, szRestCmdLine);
 
    // No connection with an existent IE was done.
    return FALSE;
 
}
 
#if 0
#define WMC_UNIX_NEWWINDOW            (WM_USER + 0x0400)
BOOL RemoteIENewWindow(LPTSTR pszCmdLine)
{
    HWND hwnd; 
    LPTSTR pszCurrent = pszCmdLine;
 
    while (*pszCurrent == TEXT(' '))
        pszCurrent++;
    if (*pszCurrent == TEXT('-'))
        return FALSE;
 
    if (hwnd = FindWindow(IEREMOTECLASS, NULL))
    {
        COPYDATASTRUCT cds;
        cds.dwData = IEREMOTE_CMDLINE;
        cds.cbData = pszCmdLine ? (lstrlen(pszCmdLine)+1)*sizeof(TCHAR) : 0;
        cds.lpData = pszCmdLine;
        SetForegroundWindow(hwnd);
        SendMessage(hwnd, WM_COPYDATA, (WPARAM)WMC_UNIX_NEWWINDOW, (LPARAM)&cds);
	printf("Opening a new window in the currently running Internet Explorer.\n");
	printf("To start a new instance of Internet Explorer, type \"iexplorer -new\".\n");
	return TRUE;
    }
    return FALSE;    
}
#endif
 
// Entry point for Mainwin is WinMain so create this function and call
// ModuleEntry() from here.
 
#if defined(MAINWIN)
EXTERN_C int _stdcall ModuleEntry(void);
 
EXTERN_C int WINAPI WinMain( HINSTANCE hinst, HINSTANCE hprev, LPSTR lpcmdline, int cmd )
{
        return ModuleEntry ();
}
#endif

Yet more information, this is all of the Registry keys installed by Internet Explorer.

iedisp.reg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
REGEDIT4
 
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application]
@="Internet Explorer"
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application\CLSID]
@="{0002DF01-0000-0000-C000-000000000046}"
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application\CurVer]
@="InternetExplorer.Application.1"
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application\NotInsertable]
@=""
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application.1]
@="Internet Explorer (Ver 1.0)"
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application.1\CLSID]
@="{0002DF01-0000-0000-C000-000000000046}"
 
[HKEY_CLASSES_ROOT\InternetExplorer.Application.1\NotInsertable]
@=""
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}]
@="Internet Explorer(Ver 1.0)"
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\LocalServer32]
@="c:\\windows\\ie96.exe"
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\ProgID]
@="InternetExplorer.Application.1"
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\VersionIndependentProgID]
@="InternetExplorer.Application"
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\TypeLib]
@="{4547D580-355D-11CF-A9BC-00AA004AE837}"
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\Programmable]
@=""
 
[HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}\NotInsertable]
@=""
 
[HKEY_CLASSES_ROOT\TypeLib\{4547D580-355D-11CF-A9BC-00AA004AE837}]
@="Internet Explorer Type Library"
 
[HKEY_CLASSES_ROOT\TypeLib\{4547D580-355D-11CF-A9BC-00AA004AE837}\1.0]
@="Internet Explorer (Ver 1.0) Type Library"
 
[HKEY_CLASSES_ROOT\TypeLib\{4547D580-355D-11CF-A9BC-00AA004AE837}\1.0\0\win32]
@="c:\windows\ie96.exe\1"

The makefile to compile Internet Explorer for Windows XP.

!ifdef NTMAKEENV
 
#
# Build using BUILD.EXE (Do not edit this section of this file, edit SOURCES)
#
!INCLUDE $(NTMAKEENV)\makefile.def
 
!endif # NTMAKEENV

There is not much source code in the explore folder, the rest would be built into Windows XP with all of the Active Desktop and ActiveX content. But it is very interesting to look at and see how it works.

Here is some code defining the IE 2.0 icon ids. Interesting…

rcids.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//---------------------------------------------------------------------------
// Defines for the rc file.
//---------------------------------------------------------------------------
 
//
// IE 2.0 icon ids
//
// NOTE for IE 2.0 compatibilty these icons MUST be in this order
//
#define RES_ICO_FRAME           32528
#define RES_ICO_HTML            32529
#define RES_ICO_EXTRA_1         32530
#define RES_ICO_EXTRA_2         32531
#define RES_ICO_EXTRA_3         32532
#define RES_ICO_EXTRA_4         32533
#define IDI_APPEARANCE          32534
#define IDI_ADVANCED            32535
#undef IDI_HOMEPAGE
#define IDI_HOMEPAGE            32536
#define IDI_GOTOURL             32537
#define IDI_FINDTEXT            32538
#define IDI_UNKNOWN_FILETYPE    32539
#define RES_ICO_JPEG            32540
#define RES_ICO_GIF             32541
#define IDI_INTERNET            32542
#define RES_ICON_FOLDER_OPEN    32543
#define RES_ICON_FOLDER_CLOSED  32544
#define RES_ICON_URL_FILE       32545
#define IDI_SECURITY            32546
#define RES_ICO_NOICON          32547
#define RES_ICO_FINDING         32548
#define RES_ICO_CONNECTING      32549
#define RES_ICO_ACCESSING       32550
#define RES_ICO_RECEIVING       32551
#define IDI_NEWS                32552
#define IDI_VRML                32553
#define IDI_MHTMLFILE           32554
 
 
// String IDS which are actually used:
#define IDS_COMPATMODEWARNING        700
#define IDS_COMPATMODEWARNINGTITLE   701
#define IDS_INTERNETEXPLORER         702
 
 
// Commmand ID
#define FCIDM_FIRST             FCIDM_GLOBALFIRST
#define FCIDM_LAST              FCIDM_BROWSERLAST
 
//---------------------------------------------------------------------------
#define FCIDM_BROWSER_FILE      (FCIDM_BROWSERFIRST+0x0020)
#define FCIDM_FILECLOSE         (FCIDM_BROWSER_FILE+0x0001)
#define FCIDM_PREVIOUSFOLDER    (FCIDM_BROWSER_FILE+0x0002)
#define FCIDM_ENTER		(FCIDM_BROWSER_FILE+0x0003)
 
// these aren't real menu commands, but they map to accelerators or other things
#define FCIDM_NEXTCTL           (FCIDM_BROWSER_FILE+0x0010)
#define FCIDM_DROPDRIVLIST      (FCIDM_BROWSER_FILE+0x0011)
 
//---------------------------------------------------------------------------
#define FCIDM_VIEWTOOLBAR     (FCIDM_BROWSERFIRST + 0x0010)
#define FCIDM_VIEWSTATUSBAR   (FCIDM_BROWSERFIRST + 0x0011)
#define FCIDM_VIEWOPTIONS     (FCIDM_BROWSERFIRST + 0x0012)
 
//---------------------------------------------------------------------------
#define FCIDM_BROWSER_HELP      (FCIDM_BROWSERFIRST+0x0100)
 
#define FCIDM_HELPSEARCH        (FCIDM_BROWSER_HELP+0x0001)
#define FCIDM_HELPABOUT         (FCIDM_BROWSER_HELP+0x0002)
 
//----------------------------------------------------------------
#define FCIDM_BROWSER_EXPLORE   (FCIDM_BROWSERFIRST + 0x0110)
#define FCIDM_NAVIGATEBACK      (FCIDM_BROWSER_EXPLORE+0x0001)
#define FCIDM_NAVIGATEFORWARD   (FCIDM_BROWSER_EXPLORE+0x0002)
#define FCIDM_BROWSEROPTIONS    (FCIDM_BROWSER_EXPLORE+0x0003)
#define FCIDM_RECENTMENU        (FCIDM_BROWSER_EXPLORE+0x0010)
#define FCIDM_RECENTFIRST       (FCIDM_BROWSER_EXPLORE+0x0011)
#define FCIDM_RECENTLAST        (FCIDM_BROWSER_EXPLORE+0x0050)
#define FCIDM_FAVORITES         (FCIDM_BROWSER_EXPLORE+0x0052)
#define FCIDM_ADDTOFAVORITES    (FCIDM_BROWSER_EXPLORE+0x0053)
#define FCIDM_FAVORITEFIRST     (FCIDM_BROWSER_EXPLORE+0x0055)
#define FCIDM_FAVORITELAST      (FCIDM_BROWSER_EXPLORE+0x0100)
#define FCIDM_FAVORITE_ITEM     (FCIDM_FAVORITEFIRST + 0)
#define FCIDM_FAVORITECMDFIRST  (FCIDM_FAVORITES)
#define FCIDM_FAVORITECMDLAST   (FCIDM_FAVORITELAST)
 
#define MH_POPUPS	700
#define MH_ITEMS	(800-FCIDM_FIRST)
#define MH_TTBASE               (MH_ITEMS - (FCIDM_LAST - FCIDM_FIRST))
#define IDS_TT_PREVIOUSFOLDER   (MH_TTBASE+FCIDM_PREVIOUSFOLDER)
#define IDS_TT_NAVIGATEBACK             (MH_TTBASE + FCIDM_NAVIGATEBACK)
#define IDS_TT_NAVIGATEFORWARD          (MH_TTBASE + FCIDM_NAVIGATEFORWARD)
#define IDS_TT_FAVORITES             (MH_TTBASE + FCIDM_FAVORITES)
#define IDS_TT_ADDTOFAVORITES          (MH_TTBASE + FCIDM_ADDTOFAVORITES)
 
// Define string ids that go into resource file
#define IDS_MH_DRIVELIST        (MH_ITEMS+FCIDM_DRIVELIST)
#define IDS_MH_MENU_FILE        (MH_ITEMS+FCIDM_MENU_FILE)
#define IDS_MH_MENU_EXPLORE     (MH_ITEMS+FCIDM_MENU_EXPLORE)
#define IDS_MH_MENU_HELP        (MH_ITEMS+FCIDM_MENU_HELP)
#define IDS_MH_FILECLOSE        (MH_ITEMS+FCIDM_FILECLOSE)
#define IDS_MH_PREVIOUSFOLDER   (MH_ITEMS+FCIDM_PREVIOUSFOLDER)
#define IDS_MH_HELPSEARCH       (MH_ITEMS+FCIDM_HELPSEARCH)
#define IDS_MH_HELPABOUT        (MH_ITEMS+FCIDM_HELPABOUT)
#define IDS_MH_NAVIGATEBACK	(MH_ITEMS+FCIDM_NAVIGATEBACK)
#define IDS_MH_NAVIGATEBACK     (MH_ITEMS+FCIDM_NAVIGATEBACK)
#define IDS_MH_NAVIGATEFORWARD  (MH_ITEMS+FCIDM_NAVIGATEFORWARD)
#define IDS_MH_RECENTMENU       (MH_ITEMS+FCIDM_RECENTMENU)
#define IDS_MH_MENU_FAVORITES   (MH_ITEMS+FCIDM_MENU_FAVORITES)
#define IDS_MH_FAVORITES        (MH_ITEMS+FCIDM_FAVORITES)
#define IDS_MH_ADDTOFAVORITES   (MH_ITEMS+FCIDM_ADDTOFAVORITES)
 
#define IDS_NAVIGATEBACKTO  720
#define IDS_NAVIGATEFORWARDTO 721
 
#define IDS_OPTIONS	722
#define IDS_TITLE	723
#define IDS_ERROR_GOTO	724
 
#define IDS_NONE        725
#define IDS_NAME        726     // Used for NAME member function for fram programmability
 
// Accelerator ID
#define ACCEL_MERGE	0x100
 
// Menu ID
#define MENU_TEMPLATE	0x100
#define MENU_FAVORITES  0x101

2 thoughts on “Some information I found about the Internet Explorer browser of old.”

  1. Do you think it’s possible to build a standalone executable of IE5 from the win2k source code? I built calc.exe with some minor esthetic changes, it took me a couple of days to get it done, my setup is Win7 and Visual Studio Express 2008 (I know it’s almost year 2024 by the way).

    Reply
    • Maybe, easier than Windows XP. IE is spread across the whole OS it seems with the Active Desktop crap. But IE was on Solaris UNIX as well, I wonder if you could build it for Linux. Or would you want to?

      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.